(一) SQL语法优化

1. select后跟具体字段,不使用select *

2. order by后字段,尽可能为索引字段

3. group by分组时会经历排序过程,group by后也尽量跟索引字段

4. 能使用where完成的条件限定,不使用having的限定

5. 数据类型尽量简单,整数比字符使用成本更小

6. 查询时尽量减少冗余数据读取,使用where子句减少返回的记录数

7. Where后面多个限定条件,应将索引列或者过滤几率书最多的条件放前面

(二) 索引优化

避免全表扫描,应考虑在where及order by等列上建立索引,并使用Explain来对select查询语句进行分析。

Explain执行计划中比较重要的字段:

select_type : 查询类型,有简单查询、联合查询、子查询等;

key : 使用的索引;

rows : 扫描的行数;

type: 表示表的连接类型;

其中type字段的值有: ALL、index、range、 ref、eq_ref、const、system、NULL(从左到右,性能从差到好)

index: Full Index Scan,index与ALL区别为index类型只遍历索引树

range: 只检索给定范围的行,使用一个索引来选择行

ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件。

const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system。

SQL 性能优化的目标:至少要达到 range 级别,要求是 ref 级别,如果可以是 consts 最好。

如何避免索引失效?

1. 模糊查询时,%放后面,避免开头模糊查询

2. 尽量避免not in和in,会导致全表扫描

3. 尽量避免使用or,如果部分字段有索引,部分不存在索引,会导致全表扫描

4. 避免在where子句中进行null值判断,可能会导致全表扫描

5. 尽量避免在where条件中等号的左侧进行表达式、函数操作,会导致数据库引擎放弃索引进行全表扫描

当数据量大时,避免使用where 1=1的条件。通常为了方便拼装查询条件,我们会默认使用该条件,数据库引擎会放弃索引进行全表扫描