mysql - 当 WHERE 子句与该列进行比较时,不使用 TIMESTAMP 列上的索引

标签 mysql sql database indexing

有两个表,例如:

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/

相关文章:

php - 使用 MySQL 执行复杂的多表搜索查询

sql - 如何使用 PostgreSQL 执行 vacuum?

java - 寻找实时解决方案 : Efficient DB interaction

c# - 删除大量记录需要很长时间

sql - 如何在 SQL 中获取当前日期时间?

php - 为数据库中的每个值在模型中放置一个常量

php - Mysql更新语句不会执行

mysql - Wtforms-将字段列表数据写入mysql

sql - 在 2 个表中的一个中查找记录

mysql - MembershipUser.ChangePassword 方法始终返回 false