使用索引进行日期和时间查找
许多真实世界的数据库表都有很多行,其中 DATETIME
或者 TIMESTAMP
列值跨越很多时间,包括数年甚至数十年。通常需要使用 WHERE
子句来检索该时间跨度的某个子集。例如,我们可能希望从表中检索 2016 年 9 月 1 日的行。
一种效率低下的方法是这样的:
WHERE DATE(x) = '2016-09-01' /* slow! */
这是低效的,因为它将函数 - DATE()
- 应用于列的值。这意味着 MySQL 必须检查 x
的每个值,并且不能使用索引。
这是一种更好的操作方法
WHERE x >= '2016-09-01'
AND x < '2016-09-01' + INTERVAL 1 DAY
这将选择在当天任何地方的 x
的值范围,直到但不包括 (因此 <
)第二天的午夜。
如果表在 x
列上有索引,则数据库服务器可以对索引执行范围扫描。这意味着它可以快速找到 x 的第一个相关值,然后按顺序扫描索引,直到找到最后一个相关值。索引范围扫描比 DATE(x) = '2016-09-01
所需的全表扫描更有效。
不要试图使用它,即使它看起来更有效。
WHERE x BETWEEN '2016-09-01' AND '2016-09-01' + INTERVAL 1 DAY /* wrong! */
它具有与范围扫描相同的效率,但它将选择值为 x
的行,正好在 2016 年 9 月 2 日午夜,这不是你想要的。