我有一个包含四列的表
|-----|-----|-----|-----------|
| a | b | c | d |
| int | int | int | timestamp |
|-----|-----|-----|-----------|
此表包含超过1亿条记录。 我在所有四列上都有索引,在(a,b,c)上有一个复合索引。
如果我运行以下查询,它可以正常工作(几毫秒):
SELECT
count(*) FROM my_table
WHERE
a = X AND b = Y AND c = Z
它基本上可以返回大约3千个元素。
但是,如果我想在列d
上添加一个条件(这是一个时间戳):
SELECT
count(*) FROM my_table
WHERE
a = X AND b = Y AND c = Z AND d < '2018-01-01T00:00:00'
然后查询响应时间会跳到几分钟。
我在这里缺少什么?
答案 0 :(得分:2)
由于(a,b,c)上有复合索引,因此第一个查询只需要使用索引(参见covering indexes的概念),因此可以非常快速地提供结果。服务器甚至不必打开表本身。
当您在列d
上添加条件时,mariadb不能再使用复合索引作为覆盖索引。该索引仍将用于加速查询以获得与前3个条件匹配的记录,但是然后mariadb必须转到大表并进一步过滤列d
而不使用使用任何索引以获得第4个标准的匹配记录。根据您的复合指数的选择程度,这仍然需要很长时间。
您可以尝试在所有4列上创建索引,但总体价格可能会高于收益。