【发布时间】:2018-10-05 11:18:42
【问题描述】:
我有一个包含大约 200 万条记录的表。它有一列包含String 格式(类似格式)的日期值。现在我需要根据这个字符串日期列过滤记录。我尝试使用STR_TO_DATE,但获取记录需要很长时间,因为该列没有INDEX。
谁能帮我添加一个Index 吗?
【问题讨论】:
我有一个包含大约 200 万条记录的表。它有一列包含String 格式(类似格式)的日期值。现在我需要根据这个字符串日期列过滤记录。我尝试使用STR_TO_DATE,但获取记录需要很长时间,因为该列没有INDEX。
谁能帮我添加一个Index 吗?
【问题讨论】:
在谓词中包装函数中的列会强制 MySQL 在每一行上评估函数,从而有效地禁用可能更有效的索引查找或范围扫描。
例如,MySQL 不能使用索引范围扫描
... FROM t WHERE STR_TO_DATE(t.mycol,'%Y-%m-%d') = '2018-04-23'
^^^^^^^^^^^^ ^^^^^^^^^^^^
但是让 SQL 引用一个裸列将允许 MySQL 考虑在适当的索引上使用范围扫描操作 ...
... FROM t WHERE t.mycol = DATE_FORMAT('2018-04-23','%Y-%m-%d')
^^^^^^^
后一个查询的合适索引处的第一次切割将是
CREATE INDEX t_IX1 ON t (mycol)
这不一定是查询的最佳索引。这真的取决于查询。例如,覆盖索引可能是更合适的选择。
问题提到将“日期”值存储为字符串,大概意思是 CHAR 或 VARCHAR 数据类型。请注意,MySQL 实现了本机 DATE 数据类型,该数据类型是为存储“日期”值而定制的。
【讨论】:
DATETIME 和 after insert trigger 的列解决了这个问题(我的表没有have update) 来更新新添加的列,读取来自VARCHAR 类型日期的值。
SET NEW.newly_added_col = ... ; 这将比 AFTER INSERT 触发器更有效。