在业务系统中,除了使用主键进行的查询,其他的我都会在测试库上测试其耗时,慢查询的统计主要由运维在做,会定期将业务中的慢查询反馈给我们。
慢查询的优化首先要搞明白慢的原因是什么?
① 是查询条件没有命中索引?
② 是load了不需要的数据列?
③ 还是数据量太大?
所以优化也是针对这三个方向来的:
1、分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者修改索引,使得语句可以尽可能的命中索引。
2、分析语句,看看是否load了额外的数据,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写。
3、如果是表中的数据量是否太大导致查询慢,可以进行横向或者纵向的分表.
MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10S以上的语句。默认情况下,Mysql数据库并不启动慢查询日志,需要我们手动来设置这个参数,当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。慢查询日志支持将日志记录写入文件,也支持将日志记录写入数据库表。
慢查询的配置:
① SQL语句中IN包含的值不应过多
MySQL对于IN做了相应的优化,即将IN中的常量全部存储在一个数组里面,而且这个数组是排好序的。但是如果数值较多,产生的消耗也是比较大的。再例如:
select id from table_name where numin(1,2,3) 对于连续的数值,能用between 就不要用in了。
② SELECT语句务必指明字段名称
SELECT *增加很多不必要的消耗(cpu、io、内存、网络带宽);增加了使用覆盖索引的可能性;当表结构发生改变时,前断也需要更新。所以要求直接在select后面接上字段名。
③ 如果排序字段没有用到索引,就尽量少排序
④ 如果限制条件中其他字段没有索引,尽量少用or
or两边的字段中,如果有一个不是索引字段,而其他条件也不是索引字段,会造成该查询不走索引的情况。很多时候使用 union all 或者是union(必要的时候)的方式来代替“or”会得到更好的效果
or查询:
(1) or两边放联合索引,不触发索引(如果两边是单列索引另算)
(2) or两边是单列索引,查询走索引
(3) or两边只要有一个不是索引就不启用索引查询
单例索引演示:
复合索引演示:
(4) or两边一个是联合索引的最左索引一个是单例索引才生效,否则失效
示例:
-- 创建单列索引
create index idx_nickname on tb_seller(nickname) ;