0

我在一个相对较大的表(约 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 上有一个单独的索引,但查询仍然比没有该部分的同一查询慢多个数量级。

如何使用索引来提高性能?

4

2 回答 2

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东西,那么这是值得的。

于 2012-08-30T17:45:25.217 回答
1

MySQL 如何使用索引中所述:

MySQL 对这些操作使用索引:

[ deletia ]

  • 查找特定索引列的MIN()或值。这由预处理器优化,该预处理器检查您是否正在使用索引中之前出现的所有关键部分。在这种情况下,MySQL 为每个or表达式执行单个键查找并将其替换为常量。如果所有表达式都替换为常量,则查询立即返回。例如:MAX()key_colWHERE key_part_N = constantkey_colMIN()MAX()

    选择最小值(key_part2),最大值(key_part2)
    FROM tbl_name WHERE key_part1 =10;

因此,当您应用过滤器时,MySQL 不能使用您定义的简单索引col_1进行查找MAX(col_1):它必须扫描所有匹配的行(尽管它可以通过对该简单索引进行排序以降序执行此操作col_1),就像由EXPLAIN查询的输出显示。

您应该在(col_2, col_3, col_4, col_1).

于 2012-08-30T17:57:34.673 回答