2
SELECT COUNT(*) AS cnt
FROM products
WHERE ExternalProductId IS NOT NULL
GROUP BY SourceId, ExternalProductId
HAVING cnt > 1

(ExternalProductId, SourceId, AnotherField) 上有一个索引。解释显示使用了索引。这打印在说明的“额外”列中:

Using where; Using index; Using temporary; Using filesort

当我运行查询时,我通过 SHOW PROCESSLIST 看到:

Copying to tmp table on disk

我可以调整这个查询以在索引上工作吗?我也不介意我得到的结果是否因为其他进程同时在此表上工作而稍微不准确 - 我可以更改隔离级别以提高查询的性能吗?

4

2 回答 2

3

如果您反转您的列GROUP BY以与复合索引的前两个字段的顺序相对应,它将更有效地使用您的复合索引。

SELECT COUNT(*) AS cnt
FROM products
WHERE ExternalProductId IS NOT NULL
GROUP BY ExternalProductId, SourceId
HAVING cnt > 1

您的查询执行平原应该变成'Using where; Using index',并摆脱由另一个造成的临时表和文件排序GROUP BY

您仍然会得到相同的结果,但顺序会略有不同。

于 2010-12-16T18:25:52.750 回答
0

有几件事可以尝试:

  1. MySQL 将自动使用 group by 进行排序。如果您不关心排序顺序,请添加“ORDER BY NULL”子句。这将取出文件排序和可能的临时表。

  2. 删除 count(*) 并使用索引中的列名而不是通配符。

还。你的指数是多少?你能告诉我们完整的表创建语句吗?

于 2010-12-16T15:35:16.733 回答