如何避免花时间在 MySQL 中创建 tmp 表

Posted

技术标签:

【中文标题】如何避免花时间在 MySQL 中创建 tmp 表【英文标题】:How to avoid spending time in creating tmp table in MySQL 【发布时间】:2015-06-25 16:56:23 【问题描述】:

我有以下 mysql 查询。

SELECT 
    COUNT(analyzer_host.server) AS count,
    analyzer_host.server AS server
FROM
    analyzer_host,
    analyzer_url,
    analyzer_code
WHERE
    analyzer_host.server IS NOT NULL
        AND analyzer_host.server != ''
        AND analyzer_code.account_id = 33
        AND analyzer_code.id = analyzer_url.url_id
        AND analyzer_url.id = analyzer_host.url_id
GROUP BY analyzer_host.server;

我对此查询进行了一些分析,这被困在 "Copying to tmp table" 中。有没有办法可以避免这种情况。还有导致查询创建 tmp 表的任何指针。

【问题讨论】:

为什么要按同一个字段进行分组和计数?如果您想要每个服务器的所有记录,只需使用 COUNT(*) 需要分组,因为稍后我将使用该信息计算应用程序中每个服务器的百分比。 是否在analyzer_host.server 列上创建了索引?这个索引对于MySql进行group by优化至关重要,阅读这个链接:dev.mysql.com/doc/refman/5.7/en/group-by-optimization.html 是的,但它也是与其他列的复合索引的一部分。 请停止使用隐式语法。这是一种 SQL 反模式,您应该在 20 多年前就停止使用它。 【参考方案1】:

第一

SELECT  COUNT(host.server) AS count, host.server AS server
    FROM  host
    JOIN  url  ON url.id  = host.url_id
    JOIN  code ON code.id =  url.url_id
    WHERE  host.server IS NOT NULL
      AND  host.server != ''
      AND  code.account_id = 33
    GROUP BY  host.server; 

这摆脱了analyzer_ 的混乱并使用JOIN...ON 语法。

其次,JOIN 似乎不太正确——url 中是否同时存在 idurl_idurl_idhosturl 之间有区别吗?

codePRIMARY KEY(account_id) 吗?这就是优化器希望开始的地方。

请提供EXPLAIN SELECT ...,以便我们查看它是否正在执行任何表扫描。如果是,那么 那个 是问题所在,而不是“tmp 表”。

如果您需要进一步讨论,请为所有三个表格提供SHOW CREATE TABLE

【讨论】:

以上是关于如何避免花时间在 MySQL 中创建 tmp 表的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat 服务器在 tmp 中创建目录

pyspark 给出以下错误无法在 /tmp 中创建本地目录

发布 AWS Amplify GraphQL 突变时如何避免在数组中创建重复项

使用聚合操作时如何避免在 data.table 中创建重复项

如何在 MS Access 中创建 Pivot 以避免一种类型的记录出现空值?

在 Unity 中创建简单可靠且干净的 UI