【问题标题】:How to avoid spending time in creating tmp table in MySQL如何避免花时间在 MySQL 中创建 tmp 表
【发布时间】: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 多年前就停止使用它。

标签: mysql sql database query-optimization sql-optimization


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多