慢查日志需要注意这样几个参数:
slow_query_log
:启动/停止记录慢查日志slow_query_log_file
:指定慢查日志的存储路径及文件long_query_time
:指定慢查日志收集SQL的执行时间阈值long_queries_not_using_indexes
:是否记录未使用索引的sql
可以看到,我云服务器上的慢查询日志是未开启的,使用set global
开启。
慢查日志暂时就介绍到这里,可以使用常用的慢查日志分析工具帮助分析。
SELECT id,‘user‘,‘host‘,DB,command,‘time‘,state,info
FROM information_schema.PROCESSLIST
WHERE TIME> =60
当前服务器,执行 时间超过60s的sql
通过脚本周期性地执行这句,就可以实时发现执行慢的sql
如果把查询看作一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间。如果要优化查询,实际上是要优化其子任务,要么消除一些子任务,要么减少子任务的执行次数。
查询性能低下最基本的原因是访问的数据太多,某些查询可能不可避免的需要筛选大量数据,但并不十分常见。大部分性能低下的查询都可以通过减少访问的数据量的方式进行优化,一般是通过下面两个步骤:
第一个步骤,需要注意自己写的sql语句。
详细说说第二个步骤。
对于Mysql来说,最简单的衡量查询开销的三个指标:
响应时间包括:服务时间和排队时间。服务时间是数据库处理这个查询真正花费的时间,而排队时间则是等待某些资源(如I/O或者锁)的时间。
这三个值需要根据实际经验来判断响应时间是否是一个合理的值,通过explain
来查看一个查询语句的各种属性。
比如:
explain
select ecm_order_id,resource
from vem_delivery
where ecm_order_id=201800013223001
EXPLAIN列的解释:
有些时候我们需要重写查询以获取更好的性能,尽管得到的结果可能不同,也许最终程序的代码也会和查询一起被改。
把一个耗时的复杂查询分解成多个简单的查询。
平时我们更倡导用尽可能少的查询做尽可能多的事情,这样可以减少网络通信开销,能减少查询解析和优化的步骤,以及代码上似乎更优雅。 但是在MySql中,MySql被设计成可以很高效地连接和断开服务器,而且能很快地响应精简的查询。在现代网络下,MySql在一般的服务器上每秒钟可以处理50000个查询。因此,对于一些耗时的复杂查询,可以通过分解查询以得到更高的效率。
比如:分解联接,把一个多表联接分解成多个单表查询,然后在应用程序端实现联接。
例如有如下的一个连接查询:
SELECT * FROM tag JOIN tag_post ON tag.id = tag_post.tag_id WHERE tag.title = ‘test’;
分解成两个查询:
SELECT * FROM tag WHERE tag.title = ‘test’; – 假设返回id有 (10,11,12,13,14,15);
SELECT * FROM tag_post WHERE tag_id IN (10,11,12,13,14,15);
这样分解查询,看似浪费,但其针对一些耗时的多表联接能带来很好的性能提升:
not in
和<>
查询查询主要分五步:
其实第2-5步是可能对查询的速度产生影响的。
对于第二步查询缓存,我们之前写的DDBS 分布式DB与Cache一致性中提到过,如果有写入数据,则会对缓存造成影响,比如写入时对缓存加锁。所以,在 读写频繁的系统使用查询缓存可能会降低查询处理的效率,在这种情况下,建议通过query_catch_type
关闭查询缓存。
其他优化,比如查询优化器内部机制不做介绍了。
如何确定查询各个阶段所消耗的时间呢?
通过使用profile即可。