MySQL是如何执行查询的

原文链接:http://www.xaprb.com/blog/2009/04/01/how-mysql-really-executes-a-query/

 

:作者说了,很多地方是愚人节的玩笑...

 

让我们看看它是如何从开始到结束的。

 

SELECT SQL_NO_CACHE COUNT(col1) FROM users
WHERE userid IN(
   SELECT userid FROM othertbl
)
ORDER BY userid DESC;

 

执行这个查询可以分为以下的几步:

   1. MySQL API将查询分解成一系列标记并发送到server。
   2. 解析查询
   3. MySQL进行权限检查。由于可能要调用一次LDAP或者活动目录,所以此步比较复杂。这里先注释掉这一步。
   4. 查询缓存进行检查。但是由于我明确的给出了SQL_NO_CACHE的指令,所以查询缓存再次并不检查。(如果没有给出SQL_NO_CACHE指令,可能会在缓存中找到一个结果集并返回它。)
   5. 优化器执行子查询并返回userid值的列表替换掉IN表达式。
   6. 优化器开始处理COUNT 表达式。就我们所知,所有的COUNT查询在MyISAM表上都能被非常快速的执行,但又有InnoDB并没有优化器,所以在InnoDB上COUNT是比较慢的。实际上,InnoDB在各方面都比MyISAM慢,所以应该经常使用MyISAM。
   7. 经过解析并优化的查询被编译成查询计划(query plan | 译者: execution plan)—— 本地的字节码,可以直接在CPU上执行。
   8. 优化过的查询计划被保存下来留为之后的查询用。如果稍后一个相似的查询发送过来,解析和编译可以被省略。而令人奇怪的是,这些都是存放在查询缓存中的。(这仅仅是那些存放在查询缓存中有趣的之一,正如我所说,执行可能并不如你所愿)
   9. 查询被执行,可能是多个CPU同时执行。如果这样的话,多个CPU的放回结果需要被结合成最终结果。此处的操作会显示在Sort_merge_passes状态中。(这就是为什么sort_buffer_size要设置的比较大,一般我推荐是可用内存的75%或者更多。)
   10. 如果userid列上没有索引,那么 ORDER BY 会被忽略。但如果有索引的话,MySQL的行锁和MVCC(server实现,并不在存储引擎中)将强制从索引中读取结果。在这种情况下,结果会被放置到一个文件中并被排序,内部名称是“filesort”,可以在EXPLAIN的输出中看到。
   11. 如果结果集比server的内存大,server也必须在磁盘上创建临时表。那样,在EXPLAIN的输出中将可以看到“Using temporary; Using disk table”。
   12. 通过一个分离的网络连接返回结果集给客户端(如此,查询才能异步)。
   13. 查询结束后,记录在MyISAM的事务日志——binary log中。如果你记录了这些log,你可以撤销之前执行的语句,如此便不需要备份了。可以仅仅用binary log来回滚修改。binary log也是MyISAM的优势之一。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值