MySQL简单但查询速度慢(索引错误?)

时间:2012-02-10 17:08:15

标签: mysql indexing

我正在处理一个简单的查询,该查询在由126,000条记录填充的myisam表中运行大约1.2秒:

SELECT * FROM my_table
WHERE primary_key != 5 AND
(
    col1 = 528 OR (col2 = 265 AND col3 = 1)
)
ORDER BY primary_key DESC

我已经为where子句中使用的每个字段创建了单个索引,但只使用了primary_key(my_table的自动增量字段)作为键,而col1和col2只是被忽略而且查询变得慢得多。我应该如何创建索引(可能是多索引)或编辑查询?

3 个答案:

答案 0 :(得分:4)

如果您有以下多列“覆盖”索引,您将获得最佳性能:

(primary_key, col1)
(primary_key, col2, col3)

并发出以下查询:

(SELECT * FROM my_table
WHERE primary_key != 5 AND
  col1 = 528)
UNION
(SELECT * FROM my_table
WHERE primary_key != 5 AND
 col2 = 265 AND col3 = 1)
ORDER BY primary_key DESC

通过基于基数更改索引中字段的顺序,您可以获得更好,更好的性能。

在原始查询中,WHERE子句中的整个选择都不能使用索引,这会导致部分表扫描。

在上面的查询中,第一个子查询能够完全利用第一个索引,避免任何表扫描,第二个子查询使用第二个索引。

不幸的是,MySQL无法利用索引对完整结果集上的记录进行排序,并且可能会使用filesort对它们进行排序。因此,如果您不需要primary_key所订购的记录,请删除外部ORDER子句以获得更好的性能,但如果结果集很小,则不应该成为问题。

答案 1 :(得分:0)

使用EXPLAIN了解发生了什么。这将识别正在使用的索引,从而使您能够调整查询。

答案 2 :(得分:0)

不幸的是,如果没有对MySQL内部的全面了解,几乎没有办法预测哪些索引比其他索引更好。但是,对于每个查询(或者,至少是子查询/连接),MySQL将只使用1个索引,您已声明主键正在使用,因此我假设您已查看EXPLAIN输出。

您可能希望以不同的顺序尝试所有(primary_key,col1,col2,col3)或其中一部分的多列索引,以找到最佳结果。最佳索引将主要取决于列的基数,因此,甚至可能会根据表中的数据随时间变化。

相关问题