假设以下SQL查询:
SELECT col1,col2 from table where col1 > 5 and col2 > 8
我相信MySQL无法使用相同的表索引在两列中查找,因为这两个条件都是范围条件。 因此,我试图了解什么是最好的方法来确定在这种情况下索引哪一列(这可能是最具选择性的一列)。
是否可以通过某种方式访问MySQL元数据,以便识别A列或B列是否更具选择性,而无需实际为两个选项创建索引并查看基数信息?
编辑:澄清一下,目标是找到一种方法来做到这一点,即使是在没有索引的情况下永远运行的查询(因此在这种情况下计算行是不可能的)。
答案 0 :(得分:2)
请注意,您的查询中只包含 <{em> col1
和col2
。这意味着INDEX(col1,col2)
和INDEX(col2,col1)
是“覆盖”。 “覆盖提供额外的提升,因为整个查询可以在索引的BTree中执行。
如果您将另一列添加到SELECT
列表,则该列将不再显示。
但问题是 命令将列放在索引中。
将其视为二维数组。 col1 > 5 and col2 > 8
指的是该2D阵列的右下角。 MySQL基本上必须扫描数组的右半部分或下半部分,因为1维索引首先按行或列排序。
优化的“新”“MRR”功能可能能够将精力集中在角落而不是一半。这是一种找出方法:
add one index
FLUSH STATUS;
SELECT ...
SELECT SESSION STATUS LIKE 'Handler%';
drop that index
现在重复另一个索引。
然后比较Handler值。最大的数字将表示触摸的索引(或数据)行的数量。
更简单的回答
如果查询中的仅列为col1
和col2
,则添加INDEX(col1, col2)
(按任意顺序排列)。
如果涉及更多列,请添加INDEX(col1)
和INDEX(col2)
。优化器在它们之间选择。
答案 1 :(得分:1)
运行此查询时出现问题吗?
select count(*),
sum(col1 > 5),
sum(col2 > 8),
sum( col1 > 5 and col2 > 8)
from t;
第二列和第三列之间的最小值是最具选择性的。
注意:将两列放在索引中仍然有价值。 MySQL应该能够使用where
子句的第二个键而不必查找数据页中的数据。