MySQL:“发送数据”vs“复制到tmp表”

时间:2015-09-30 17:47:00

标签: mysql query-optimization

我有2个查询执行相同的操作并给出相同的结果集,但写的方式不同。查看他们的个人资料,他们几乎同时执行:大约0.075秒

令人着迷的是,查询#1几乎占用了“复制到tmp表”状态的整个流程执行时间。由于查询#2几乎占用了“发送数据”状态的整个流程执行时间。

所以,我的问题是:

对于MySQL查询花费所有时间,“发送数据”或“复制到tmp表”更好的状态是什么状态?

查询#1(在“复制到tmp表”状态下花费执行时间)

val pipeline = ListMap(("a" -> obj1), ("b" -> obj2), ("c" -> obj3))

查询#2(在“发送数据”状态下花费执行时间)

val initial_value = Something("foo", "bar")
val result = obj3.func(obj2.func(obj1.func(initial_value)))

修改

根据jkavalik请求,我添加了EXPLAIN。我不确定如何在文本中添加它,所以我添加了图像。希望没关系。

EXPLAIN for query#1

enter image description here

EXPLAIN for query#2 enter image description here

1 个答案:

答案 0 :(得分:0)

复制到tmp表:服务器正在复制到内存中的临时表。

发送数据:线程正在读取和处理SELECT语句的行,并将数据发送到客户端。由于在此状态期间发生的操作往往会执行大量磁盘访问(读取),因此它通常是给定查询生命周期中运行时间最长的状态。

http://dev.mysql.com/doc/refman/5.6/en/general-thread-states.html

大多数查询都会发送数据,但查询状态在快速查询上会发生如此快速的变化,您甚至都不会注意到它。但是,由于您注意到它,当时可能会有很多IO正在进行中。当您运行该查询时,在终端窗口中还要查看iostat -x 10并观察磁盘IO等待(假设您使用的是Linux / Unix)。如果等待开始,MySQL正在从磁盘读取,完成其工作,然后准备将数据推送到客户端。

复制到tmp表意味着将查询或子查询的一部分结果移动到内存中,以便可以使用该临时数据(临时表)完成更多工作。每当我遇到这种状态时,都有可能进行优化。如果查询需要几秒钟才能返回,我会更关注这两种状态。在你的情况下我会优化查询1。您可能想尝试增加innodb_buffer_pool_size(假设您使用的是innodb引擎)

https://dev.mysql.com/doc/refman/5.5/en/innodb-buffer-pool.html