Glasnhost Asked: 2017-11-24 11:21:00 +0800 CST2017-11-24 11:21:00 +0800 CST 2017-11-24 11:21:00 +0800 CST 字段日期部分的索引? 772 我有一个日期时间字段,但我经常查询日期部分,就像这样 select * from table where date(datetime_field)=curdate() 此查询不能在 datetime_field 上使用索引!代码或数据库更改最少的最佳解决方案是什么? 附言。如果有我还不知道的解决方案,升级 mysql 可能是一个选项,但是 5.6 的更短期解决方案将不胜感激 mysql index 2 个回答 Voted Best Answer Michael - sqlbot 2017-11-24T19:38:07+08:002017-11-24T19:38:07+08:00 问题不在于索引。问题是您编写的查询不允许使用索引。 修改您的查询,以便将日期范围解析为一对常量并解决问题: WHERE datetime_field >= CURDATE() AND datetime_field < DATE_ADD(CURDATE(), INTERVAL 1 DAY) 这将使用列上的索引。 通常,永远不要将列用作函数的参数,WHERE因为这会强制进行表扫描。 Vérace 2017-11-24T11:41:31+08:002017-11-24T11:41:31+08:00 如果您升级,有很多解决方案适合您。 你可以有: CREATE TABLE my_table ( field_1 TYPE_1 NOT NULL, -- &c... field_2 TYPE_2 NOT NULL, --.. .. datetime_field DATETIME, .. field_n TYPE_N, -- ... my_date_field DATE GENERATED ALWAYS AS (DATE(datetime_field)) VIRTUAL, INDEX my_date_field_ix (my_date_field) ); GENERATED(又名COMPUTED或CALCULATED)字段可用于MySQL 5.7.6上!如果您不能/不想升级,那么常见的解决方案是使用触发器来实现。此解决方案的优势在于您无需任何额外存储空间 ( VIRTUAL),但如今 HDD 如此便宜,这不再是真正的问题! 服务器免费、免费且无偿提供此便利功能。您的数据仍然存储在一个且只有一个地方 SPOT(单点真相 - 或SSOT),因此没有数据重复/不一致问题,您可以INDEX“免费”使用。试一试 - 我认为它们很棒! 注意到@Michael- sqlbot的回复 - 对于这种情况更优雅,但有时,可能很难使您的查询参数可搜索!
问题不在于索引。问题是您编写的查询不允许使用索引。
修改您的查询,以便将日期范围解析为一对常量并解决问题:
这将使用列上的索引。
通常,永远不要将列用作函数的参数,
WHERE
因为这会强制进行表扫描。如果您升级,有很多解决方案适合您。
你可以有:
GENERATED
(又名COMPUTED
或CALCULATED
)字段可用于MySQL 5.7.6上!如果您不能/不想升级,那么常见的解决方案是使用触发器来实现。此解决方案的优势在于您无需任何额外存储空间 (VIRTUAL
),但如今 HDD 如此便宜,这不再是真正的问题!服务器免费、免费且无偿提供此便利功能。您的数据仍然存储在一个且只有一个地方 SPOT(单点真相 - 或SSOT),因此没有数据重复/不一致问题,您可以
INDEX
“免费”使用。试一试 - 我认为它们很棒!注意到@Michael- sqlbot的回复 - 对于这种情况更优雅,但有时,可能很难使您的查询参数可搜索!