如何在不创建索引的情况下检索MySQL中的列选择性元数据?

时间:2017-11-19 14:42:21

标签: mysql sql indexing sqlperformance

假设以下SQL查询:

SELECT col1,col2 from table where col1 > 5 and col2 > 8

我相信MySQL无法使用相同的表索引在两列中查找,因为这两个条件都是范围条件。 因此,我试图了解什么是最好的方法来确定在这种情况下索引哪一列(这可能是最具选择性的一列)。

是否可以通过某种方式访问​​MySQL元数据,以便识别A列或B列是否更具选择性,而无需实际为两个选项创建索引并查看基数信息?

编辑:澄清一下,目标是找到一种方法来做到这一点,即使是在没有索引的情况下永远运行的查询(因此在这种情况下计算行是不可能的)。

2 个答案:

答案 0 :(得分:2)

请注意,您的查询中只包含 <{em> col1col2。这意味着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值。最大的数字将表示触摸的索引(或数据)行的数量。

更简单的回答

如果查询中的列为col1col2,则添加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子句的第二个键而不必查找数据页中的数据。