select * 优化
选取业务想要的字段返回,而不是所有的字段返回。不然网络IO 太大了。
查询条件中有非索引字段和索引字段
其实是肯定会走索引的,那不然所有查询语句都全表查?肯定不合理呀,而且查询条件有时候还存在多个索引,早起mysql版本中优化器会选择一个索引,但新版本的mysql使用了index merge的优化,可以使用多个索引。所以如果你的查询条件有多个字段,其实有索引字段和非索引字段,那么肯定会使用索引的。
order by 加索引
有的时候,可以对order by 的字段也加上索引,这里给出官网的order by 的优化,其实官方没说一定会走索引,其实还是要比较性能,比如:
SELECT * FROM t1
ORDER BY key_part1, key_part2;
因为 select * 的问题,导致全表查效率其实比走索引更快一些。官方的说法就是:The index will be used if the WHERE clause is selective enough to make an index range scan cheaper than a table scan。
其中也包括加不加desc这种。下面这些情况下不会走索引:
- The query uses ORDER BY on different indexes:
order by 是不同的索引。 - The query mixes ASC and DESC:
混合ASC and DESC。
SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC;
-
order by中只使用了一部分索引,也不是最左匹配索引
-
where 条件的索引和order by 索引不同,则不会使用
SELECT * FROM t1 WHERE key2=constant ORDER BY key1;
- order by 索引做了处理的
SELECT * FROM t1 ORDER BY ABS(key);
order by 和 limit 优化
如下的语句:
order by a limit 10
这里有一个问题存在,如果a=110 的数据有15条:
- limit 0,10
- limit 10,10
这两个limit的语句查询的结果会有重复,因为 a=110 的记录有 15条,但是不知道15条中哪 10条会被 limit 0,10 取到返回,所以上面两个语句查询的结果会有重复结果出现。所以排序需要利用唯一主键来排序最好,如果没有利用主键来做排序,就像上面的语句order by a ,我们可以加一个条件,比如主键id,order by a,id ,这样会根据id来做排序,可以避免重复问题
limit 优化
如果全表的limit 查询特别慢,特别是多次的查询,语句如下:
SELECT * FROM table1 LIMIT offset, rows
这种全表查询太慢了,所以我们可以:
SELECT * FROM table1 where id >= offset LIMIT offset, rows
利用主键id来走索引查询,优化这个问题。当然如果不是全表查询,自身where 语句带有条件,那么你就需要对条件加联合索引,利用联合索引来优化条件。
or 走不走索引
-
如果 or 条件前后都有索引在,
优化后的index merge 机制会走索引 -
连表查询
连表查询是肯定不走or 索引的 -
or 前后一个有索引,一个无索引
全表查询,不走索引