Select语句优化:
- 尽量避免全表扫描, where 及 order by 涉及的列上考虑建立索引
- 避免在SQL里做函数计算
- 避免索引的最左匹配原则失效
- 索引的范围至少要达到range
- 使用覆盖索引可以避免回表
- 避免在 where 子句中使用 不等于:!= 或 <> 操作符,会造成索引失效
- 禁用or,所有使用or的地方,都可以使用unit all进行替换
- 慎用in,禁止not in,使用between以及existst很多时候是一个好的选择
- 禁止where 条件中对字段进行表达式运算及函数操作
- 禁用select * from table,只查询需要的字段。
- 正确使用联合索引时,where中字段顺序与索引顺序应当一致,且最左侧字段必须避免索引失效
- 小表关联大表,from <left_table> <join_type> JOIN <right_table>
若from table1 left join table2=》table1应该是小表,talbe2应该是大表
若from table1 right join table2=》table2应该是小表,talbe1应该是大表 - 效率上来看:count(字段)<count(主键id)<count(1)≈count(*),但应该注意业务逻辑的准确性,即使用不同的的count时,对null的行的处理是不一样的。且应该避免使用没有where条件count,即全表count,在有group by 的情况下,有时候组合索引会起到意想不到的作用
- 正确使用在类型,避免隐式转换,索引失效,on条件及where条件
- 涉及到统计聚合类的业务,应当对历史数据统计好进行存储,再组合上当前的数据进行查询
- Where字句中的连接顺序,MySQL采用从左往右,自上而下的顺序解析where子句,故过滤数据多的条件往前放,最快速度缩小结果集
- Unit 与Unit All的选择:Unit All不会去重,而Unit则会加上distinct,从则导致对整个临时表的数据做唯一性校验,这样自然会消耗更多
- 禁止在一张在表使用没有where语句,以及返回大批量的数据,所有大表的数据返回都应当分页
- Where与having的选择:除非一定要使用having,否则都使用where
- Group by: MySQL对所有GROUP BY col1,col2...的字段进行排序,在某些业务场景下,并不需要排序时,则可以指定ORDER By NULL禁止排序,避免排序结果的消耗
- Order by :能不排序就不排序。若一定要排序,优先:通过有序索引顺序扫描直接返回有序数据: order by 条件要与where中条件一致顺序一致,否则order by不会利用索引进行排序。其次使用filesort时,最好能使用单路排序算法进行排序,max_length_for_sort_data的大小和Query 语句所取出的字段类型大小总和来判定一次扫描算法还是双路排序算法。
优化filesort:加大 max_length_for_sort_data 参数的设置;去掉不必要的返回字段;增大 sort_buffer_size 参数设置 - Limit优化:
在索引排序完成排序分页的操作,最后根据主键关联回原表查询所需要的其他列内容;
把limit m,n 转换成 limit n的查询,通过m,n计算出一个位置,使用where条件然后从这个位置开始limit n,例如:
假设某张记录表,主键连续递增,中间不断层,则要先根据m,nt计算出id的位置,然后使用where id >位置 limit n进行分页 - 子查询优化:尝试转化成关联查询有时候是一个不错的选择,原则是相关子系统都可以转换成关联查询
网友评论