我有一个如下所示的查询:
SELECT * from foo
WHERE days >= DATEDIFF(CURDATE(), last_day)
在这种情况下,days
是INT
。 last_day
是DATE
列。
所以我在days
和last_day
需要两个单独的索引?
答案 0 :(得分:5)
此查询谓词days >= DATEDIFF(CURDATE(), last_day)
本质上不是sargeable。
如果保留当前的表设计,您可能会从(last_day, days)
上的复合索引中受益。然而,满足查询将需要对该索引进行全面扫描。
其中一列或两者上的单列索引对于提高此查询的性能将毫无用处或更糟。
如果您必须让此查询执行得非常好,则需要稍微重新组织您的表。让我们明白这一点。看起来您正试图排除“过期”记录:您想要expiration_date < CURDATE()
。 那是一个可搜索的搜索谓词。
因此,如果您向表中添加了新列expiration_date
,然后按如下所示进行设置:
UPDATE foo SET expiration_date = last_day + INTERVAL days DAY
然后将其编入索引,您的查询效果会很好。
答案 1 :(得分:0)
你必须小心索引,它们可以帮助你阅读,但它们会降低插入的性能。
您可以考虑在last_day字段上创建分区。
我应该尝试仅在last_day字段中创建,但是,我认为最好的是使用不同的配置进行一些性能测试。
答案 2 :(得分:0)
由于您在where条件中使用表达式,因此mysql将无法在这两个字段中的任何一个上使用索引。如果你经常使用这个表达式并且至少有mysql v5.7.8,那么你可以创建一个generated column并在其上创建一个索引。
另一个选项是创建常规列并将其值设置为此表达式的结果并为此列编制索引。您将需要触发器来保持更新。