您的位置:首页 > 数据库 > MySQL

MYSQL查询SQL的注意事项和一些技巧总结

2015-11-01 14:41 821 查看
在编写查询SQL的时候,有一些技巧可以提升查询性能,总结如下:

not exists 代替 not in

尽量避免not in (子查询)的查询,如果是not in (列表)倒是可以接受的,因为not in (子查询)可以使用not exists代替,使用not exists那么就将子查询变成和关联查询,至少可以使用主键的索引了。

迎合和讨好mysql的优化器,让查询sql走索引;

举个例子,比如,你的一张表的主键ID是从1开始的,那么

select * from t_x order by id

如果对上面的sql调整为如下:

select * from tx where id > 0 order by id

那么这样是不好的,原因就是使用了索引排序,这就是使用了顺序扫描索引,由于该索引未能覆盖查询的所有列,因此从一条索引记录移动到下一条记录时,不得不每扫描一条一条索引记录就都回表查询一次对应的行。这基本上都是随机I/O,因此,这种情况下按照索引顺序读取数据的速度通常表顺序地全表扫描慢。

如果需求的sql如下:

select id from t_x order by id

如果对上面的sql调整如下:

select id from t_x where id > 0 order by id

那么explain的查询计划的type就是rang了,这里有个点需要注意,rows的函数比 select id from t_x order by id这个要多,但是 select id from t_x order by id这个的explain 的type 是index;

总结:如果要使用索引扫描来排序,要避免排序的索引不能覆盖查询的列的情况。因此,设计索引时,如果可能,设计索引时要能满足一个索引既可以满足排序,又可用于查找行(即覆盖查询的列)。

另外注意:就算你想使用索引排序的功能,也不是任何情况都可以可以使用索引排序,这里有一些需要注意的地方,比如多表关联时,order by的字段全部为第一个表时,才能使用索引排序。order by 子句和查找型查询的限制是一样的:需要满足索引的最左前缀的要求,否则,MYSQL都需要执行排序操作,而无法利用索引排序。

有一种情况order by 子句可以不满足索引的最左前缀的要求,就是前导列为常量的时候。注意:这个前导列一定是最左前缀。其实,这样算作曲线满足order by 子句的索引的最左前缀的要求了吧。

延迟关联查询

如果关联查询的结果是所有列,或者查找的索引不能覆盖查询的列,那么就要把查询所有列的查询进行延迟关联,先通过索引查询出索引列(索引覆盖),然后和查询所有列的查询进行关联,这就是延迟关联。

4.避免多个范围查找

如果多个范围查找,那么第一个范围查找可以使用索引,后面的范围查找就不能使用了索引。但是对于多个等值条件查询(即使用in(x,y,z))则没有这个限制。虽然范围查找和in的执行计划的type列都是range,从explain的输出很难区分MYSQL是要查找范围值,还是查询列表值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: