我在一个相对较大的表(约 2000 万行)上使用以下查询:
SELECT
MAX(`col_1`)
FROM `table`
WHERE
col_2 = X AND
col_3 = Y AND
col_4 = Z
WHERE
我在 col_2、col_3 和 col_4 列上有一个组合索引,在 col_1 上有一个单独的索引,但查询仍然比没有该部分的同一查询慢多个数量级。
如何使用索引来提高性能?
我在一个相对较大的表(约 2000 万行)上使用以下查询:
SELECT
MAX(`col_1`)
FROM `table`
WHERE
col_2 = X AND
col_3 = Y AND
col_4 = Z
WHERE
我在 col_2、col_3 和 col_4 列上有一个组合索引,在 col_1 上有一个单独的索引,但查询仍然比没有该部分的同一查询慢多个数量级。
如何使用索引来提高性能?
您可以尝试col_1
在第四个位置建立索引,但很大程度上取决于表的结构(即单行的权重)。当计算MAX
,col_1
没有WHERE
时,信息可以立即通过索引获得(只要走它总是保持在左边,就像它一样)。
添加一个WHERE
,它不再是这样。您的查询很可能已经优化。通过了解 X、Y 和 Z 的类型和分布,可以(也许)进行进一步的改进。
(一个愚蠢的例子:假设col_2
,col_3
并且col_4
已知在 (-255,+255) 范围内。然后你可以考虑添加一个额外的非规范化列保存(((col_1+255)*512+(col_2+255))*512+(col_3+255))
和索引 和col_1
。甚至可能基于该索引进行聚类。这个如果您可以找到一个具有相当小的数据类型结果的单射函数,并且您经常在 X、Y 和 Z 上运行“精确”查询,即没有任何WHERE col_2 BETWEEN X1 AND X2
东西,那么这是值得的。
如MySQL 如何使用索引中所述:
MySQL 对这些操作使用索引:
[ deletia ]
因此,当您应用过滤器时,MySQL 不能使用您定义的简单索引col_1
进行查找MAX(col_1)
:它必须扫描所有匹配的行(尽管它可以通过对该简单索引进行排序以降序执行此操作col_1
),就像由EXPLAIN
查询的输出显示。
您应该在(col_2, col_3, col_4, col_1)
.