Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:“发送数据”与“复制到tmp表”_Mysql_Query Optimization - Fatal编程技术网

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

MySQL:“发送数据”与“复制到tmp表”,mysql,query-optimization,Mysql,Query Optimization,我有两个查询,它们做相同的事情,给出相同的结果集,但编写方式不同。查看它们的配置文件,执行它们所用的时间几乎相同:大约0.075秒 有趣的是,query1占用了复制到tmp表的状态中几乎所有的进程执行时间。As query2在发送数据的状态下几乎占用整个进程的执行时间 所以,我的问题是: MySQL查询的所有时间都花在发送数据或复制到tmp表上,哪个状态更好 query1在复制到tmp表的状态中花费执行时间 SELECT ac.album_category_id, ac.name, ac2.al

我有两个查询,它们做相同的事情,给出相同的结果集,但编写方式不同。查看它们的配置文件,执行它们所用的时间几乎相同:大约0.075秒

有趣的是,query1占用了复制到tmp表的状态中几乎所有的进程执行时间。As query2在发送数据的状态下几乎占用整个进程的执行时间

所以,我的问题是:

MySQL查询的所有时间都花在发送数据或复制到tmp表上,哪个状态更好

query1在复制到tmp表的状态中花费执行时间

SELECT ac.album_category_id, ac.name, ac2.album_category_id, ac2.name, ac2.description, t2.total
FROM album_category ac
JOIN album_category ac2 ON ac2.parent_album_category_id = ac.album_category_id
JOIN (
    SELECT a.album_category_id cat_id, SUM(result.count_image) total
    FROM album a
    JOIN (
        SELECT IFNULL(a.parent_album_id, a.album_id) p_album_id, COUNT(ai.image_id) count_image
        FROM album_image ai
        JOIN album a ON a.album_id = ai.album_id
        JOIN image i ON i.image_id = ai.image_id
        WHERE i.is_listed = 1
        GROUP BY p_album_id
    ) result ON result.p_album_id = a.album_id
    GROUP BY a.album_category_id
) t2 ON t2.cat_id = ac2.album_category_id
ORDER BY ac.position, ac2.position
query2在发送数据的状态下花费执行时间

SELECT ac.album_category_id, ac.name, ac2.album_category_id, ac2.name, ac2.description, t3.total
FROM album_category ac
JOIN album_category ac2 ON ac2.parent_album_category_id = ac.album_category_id
JOIN (
    SELECT a2.album_category_id cat_id, SUM(t2.sum_image) total
    FROM album a2
    JOIN (
        SELECT IFNULL(a.parent_album_id, a.album_id) p_album_id, SUM(t1.count_image) sum_image
        FROM album a
        JOIN (
            SELECT ai.album_id album_id, COUNT(ai.image_id) count_image
            FROM album_image ai
            JOIN image i ON i.image_id = ai.image_id
            WHERE i.is_listed = 1
            GROUP BY ai.album_id
        ) t1 ON t1.album_id = a.album_id
        GROUP BY p_album_id
    ) t2 ON t2.p_album_id = a2.album_id
    GROUP BY a2.album_category_id
) t3 ON t3.cat_id = ac2.album_category_id
ORDER BY ac.position, ac2.position
编辑

根据jkavalik的请求,我添加了解释。我不知道如何在文本中添加它,所以我添加了图像。希望没问题

解释问题1

解释问题2 复制到tmp表:服务器正在复制到内存中的临时表

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

在大多数查询中都会发送数据,但在快速查询中,查询状态的变化非常快,以至于您甚至不会注意到它。然而,既然你注意到了这一点,那时候可能会发生很多IO。当您运行该查询时,在终端窗口中还可以查看iostat-x10,并观察磁盘IO等待(假设您使用的是Linux/Unix)。如果等待出现,MySQL将从磁盘读取数据,完成工作,然后准备将数据推送到客户端

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


要了解这一点,您需要使用检查查询执行计划。请将这两个查询的计划添加到问题中。好的,我已经编辑了问题并添加了解释