有两个表,例如:
FOO(ID, A, B, C, D, E, G(timestamp))
BAR(ID, X, Y, Z, FK_FOO_ID, W)
并具有索引
,例如:
CREATE INDEX IDX_TEST ON FOO(G)
以下DESCRIBE
查询将不使用创建的索引:
DESC SELECT F.A, F.B, F.C, F.D, F.E,
SUM(CASE WHEN B.X IN (0, 12) THEN B.Y ELSE 0.00 END) AS 'Something_1',
SUM(CASE WHEN B.X IN (0, 12) THEN B.Z ELSE 0.00 END) AS 'Something_2',
SUM(CASE WHEN B.X = 2 THEN B.Y ELSE 0.00 END) AS 'Something_3',
SUM(CASE WHEN B.X = 2 THEN B.Z ELSE 0.00 END) AS 'Something_4'
FROM FOO AS F
INNER JOIN BAR AS B ON F.ID = B.FK_FOO_ID
WHERE
(F.G > '2018-03-01 23:59:59' OR F.G IS NULL) AND
B.W <= '2018-03-01 23:59:59' AND
B.X IN (0, 2, 12)
GROUP BY
F.A,
F.B,
F.C,
F.D,
F.E;
但从 WHERE
子句中删除 F.G > '2018-03-01 23:59:59'
,创建了索引将被应用。有什么想法吗?如何“强制”MYSQL 在 G
类型为 TIMESTAMP
的列上使用索引?对于使用此类 SELECT
查询创建更好的索引有什么想法吗?
最佳答案
优化器根据统计信息(即列中不同值出现的频率)决定是否使用索引。
在您的情况下,当您删除 F.G > '2018-03-01 23:59:59' 条件时,剩下的条件只是检查是否为 null,这是一个更常见的值。
更重要的是,当检查 null 时,它不会检查列中的值本身,而是每行都有一个位来告诉它列中的值是否为 null。这使得速度更快。
当您将条件添加回来时,它可能会更快地首先找到匹配的 ID,然后检查 G 是否匹配。
它还将使用主键,因为它需要使用它来获取
的值F.A, F.B, F.C, F.D, F.E,
如果您确实希望它使用您的索引,您可能需要将其设为覆盖索引,这意味着您需要将这些列添加到索引中
关于mysql - 当 WHERE 子句与该列进行比较时,不使用 TIMESTAMP 列上的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55475469/