mysql - Between 子句的正确索引

标签 mysql indexing

我将在其中运行查询的表上的正确索引是什么

SELECT * FROM table WHERE NOW() BETWEEN date1_col AND date2_col

date1_col 上的索引是否足够,或者我必须为两列建立索引,或者需要复杂的索引?

此外,是否会为每一行计算NOW()?在构造查询时将其作为文字提供会更好吗?

最佳答案

BETWEEN date_1 AND date_2 无法优化。但是,优化器将在运行时在这些之间进行选择:

INDEX(date_1, date_2) if the date is near the end of the date_1 values, or
INDEX(date_2, date_1) if the date is near the start of that index.

因此,拥有这两个索引。在最坏的情况下,查询将不得不扫描近一半的表。

那么,为什么不只使用 1 列版本呢?让我们进一步剖析一下......索引是根据指定列排序的 B+Tree。这样的树可以高效地进行线性扫描(从开始到日期或从日期到结束,取决于哪个索引),但之后需要检查 date_1/2 的另一个。

如果您只有 INDEX(date_1),那么它必须进入数据所在的 BTree 来获取 date_2 来检查它。

另一方面,如果您使用 INDEX(date_1, date_2),则该值就在那里,并且可以更快地测试“附加条件”。在非 JSON EXPLAIN 中,由 Extra 列中的“使用索引条件”指示。这是“ICP”。

我认为(但不确定)仅使用 2 列索引会更好。

注意:我认为 ICP 是在 5.6.10 中添加的。所以这取决于您的版本有多旧。

“覆盖”索引是指包含SELECT 中提到的所有 列的索引。这甚至更好,但它有一定的局限性,因为将 SELECT user 更改为 SELECT user, foo 使这些不再“覆盖”:

INDEX(date_1, date_2, user)
INDEX(date_2, date_1, user)

关于mysql - Between 子句的正确索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41699516/

相关文章:

mysql - Spring Hiberbate SaaS 重新加载数据库信息

php - 我怎样才能解决这个简单的 php MySQL 搜索查询

带有 mysql 查询插入的 Python - 单个参数

php - 在php中同时从两个MySQL表中选择数据

c++ - 制作索引创建类

java - 如何检查遍历是否已达到 Java 二维数组中的某个索引?

php - 无法通过 PHP 将数据插入 MySQL 数据库

sql - 为什么 SQL Server 不将索引用于非常相似的日期时间查询?

postgresql - 在我的数据库上建议适当的索引

database - 聚集索引与索引查找