Mysql优化系列之查询性能优化前篇1
前言
这是优化系列的最后一篇的第1小篇,我们其实可以直接从sql怎么写讲起,why not?但是我还是决定花2个篇幅
问一些问题,带着几个问题循序渐进的往下走。
- 一个sql语句是怎么被执行的?
- sql中关键字的执行顺序是怎样的?
- 什么是扫描?
- 为什么查询会慢?
- 什么是慢查询?
第一个问题:sql是怎么被执行的?
下图用的网上的一张流程图,省略了建立连接的过程。比较重要的几步:查询缓存,语法检查,语义检查,查询优化器,执行计划
其中查询缓存大家应该都见过,一条耗时较长的sql,过一会儿再查询的话几乎迅速就返回了结果。
第二个问题:sql执行的顺序是怎样的?
SELECT DISTINCT < select_list > FROM < left_table > < join_type > JOIN < right_table > ON < join_condition > WHERE < where_condition > GROUP BY < group_by_list > HAVING < having_condition > ORDER BY < order_by_condition > LIMIT < limit_number >
上面是一个接近标准的sql模板,但是,实际的执行顺序却是这样的
1:FROM <left_table> 2:ON <join_condition> <join_type> 3:JOIN <right_table> 4:WHERE <where_condition> 5:GROUP BY <group_by_list> 6:HAVING <having_condition> 7:SELECT 8:DISTINCT <select_list> 9:ORDER BY <order_by_condition> 10:LIMIT <limit_number>
另外注意:第4步中mysql对于where子句的条件是按照从左到右顺序过滤的,这也是为什么能过滤掉最多结果的条件要前置
第三个问题:什么是扫描?
所谓扫描,就是查询过程中可能出现的对记录或索引遍历来找到满足条件的记录。我们的期望是扫描行数越少越好。
另外在此之前请自行补充join操作中的笛卡尔积的概念以及中间表的概念
第四个问题:为什么查询慢?
让我们站高点:查询最重要的是响应时间。通过上面的sql执行过程我们想象查询是一个任务,往下分为很多子任务,每个任务都会
消耗一点时间。网络,CPU计算,生成执行计划,锁等待以及各种I/O操作都要时间,如果一个查询很慢,大面上应该先查看CPU运转
是否慢,内存是否不足。我们暂时不考虑这类的情况。
我们集中精力要优化的是:是否有额外操作,是否有额外重复的执行,哪些操作执行太慢等
最后一个问题:慢查询是什么?
show variables like "%query%",这个命令可以查询到以下几个关键变量:
slow_query_log:慢查询日志开启状态
slow_query_log_file:慢查询日志位置
long_query_time:慢查询的指定阈值,超过该值被归为慢查询
类似命令查出log_queries_not_using_indexes:未使用索引的查询
Mysql会根据配置的策略,记录慢查询的sql语句,这也是sql优化的一个切入口