选择查询似乎未使用最合适的索引

问题描述 投票:0回答:1

我有一个大约有 80 列的表。其中一些已编入索引。其中包括

age
shoesize
height
- 均为整数。

然后我有一个正在尝试优化的查询:

select * from people where age > 18 and shoesize > 10 and height > 150

为了尝试加快查询速度,我为相关三列创建了一个新的组合索引 -

age
shoesize
height
。我把这个索引称为
combinedIndex

如果我然后跑步:

explain select * from people where age > 18 and shoesize > 10 and height > 150

然后我看到这个输出:

id = 1
select_type = SIMPLE
table = people
type = ALL
possible_keys = age, shoesize, height, combinedIndex
key = NULL
key_len = NULL
ref = NULL
rows = 8947017
extra = using where

因此,运行我的查询时似乎没有使用索引。

我希望我的

combinedIndex
肯定会被使用。

我正在使用 MariaDB 10.6.19

我哪里做错了?谢谢你

sql mariadb query-optimization
1个回答
0
投票

多列 BTREE 索引(在 MariaDB / MySQL 和其他使用 BTREE 的 DBMS 中)对于处理不等式谓词的适用性有限。

您的多列索引是

(age, shoesize, height)
。它可以很好地处理这个查询。

SELECT *
  FROM people
 WHERE age = 18 AND shoesize = 10 AND height = 150

并且,它可以很好地处理这个问题,前两个索引列被测试是否相等,而仅最后一个索引列包含不等式。 SELECT * FROM people WHERE age = 18 AND shoesize = 10 AND height > 150

这是因为查询规划器可以随机访问索引到满足您条件的第一个条目,然后顺序扫描索引以获取其余条目。

但是您的查询包含三个不等式。

SELECT * FROM people WHERE age > 18 AND shoesize > 10 AND height > 150

为此,它可以使用 
age > 18

随机访问索引到第一个条目,但它必须检查索引其余部分中的所有内容,获取一些条目并丢弃其他条目以处理其他两个不等式。

毫无疑问,MySQL 的查询规划器将执行此操作的成本与仅在表中检查行并获取一些行的成本进行了比较。它认为在你的桌子上翻来翻去更便宜,所以它就这么做了。

请注意,为了满足

SELECT *

,它必须查看表的实际行。

您可能会让规划器在该查询中使用您的索引,因为您的索引
覆盖

表。

SELECT age, shoesize, height FROM people WHERE age = 18 AND shoesize = 10 AND height > 150


© www.soinside.com 2019 - 2024. All rights reserved.