Mysql 这里应该为哪些键编制索引以使此查询成为最佳查询

Mysql 这里应该为哪些键编制索引以使此查询成为最佳查询,mysql,datetime,indexing,query-optimization,Mysql,Datetime,Indexing,Query Optimization,我有一个如下所示的查询: SELECT * from foo WHERE days >= DATEDIFF(CURDATE(), last_day) 在这种情况下,days是一个INTlast_day是一个DATE列 所以我需要两个单独的索引,分别是天和最后一天 必须小心使用索引,它们可以帮助您阅读,但会降低insert的性能 您可以考虑在LayStayDayfield上创建一个分区。 我应该试着只在“最后一天”字段中创建,但是,我认为最好是使用不同的配置进行一些性能测试 必须小心使

我有一个如下所示的查询:

SELECT * from foo
  WHERE days >= DATEDIFF(CURDATE(), last_day)
在这种情况下,
days
是一个
INT
last_day
是一个
DATE


所以我需要两个单独的索引,分别是
最后一天

必须小心使用索引,它们可以帮助您阅读,但会降低insert的性能

您可以考虑在LayStayDayfield上创建一个分区。


我应该试着只在“最后一天”字段中创建,但是,我认为最好是使用不同的配置进行一些性能测试

必须小心使用索引,它们可以帮助您阅读,但会降低insert的性能

您可以考虑在LayStayDayfield上创建一个分区。


我应该试着只在“最后一天”字段中创建,但是,我认为最好是使用不同的配置进行一些性能测试

这个查询谓词,
days>=DATEDIFF(CURDATE(),last_day)
,本质上不是

如果您保持当前的表设计,您可能会从
(last_day,days)
上的复合索引中获益。然而,满足查询需要对该索引进行完整扫描

其中一列或两列上的单列索引对于提高此查询的性能是无用的或更糟的

如果您必须让这个查询执行得很好,那么您需要稍微重新组织一下您的表。让我们想想。看起来您正试图排除“过期”记录:您想要
过期日期
。这是一个可搜索谓词

因此,如果您在表中添加了一个新列
expiration\u date
,然后将其设置为:

 UPDATE foo SET expiration_date = last_day + INTERVAL days DAY

然后对它进行索引,您将有一个性能良好的查询。

这个查询谓词,
days>=DATEDIFF(CURDATE(),last_day)
,本质上不是

如果您保持当前的表设计,您可能会从
(last_day,days)
上的复合索引中获益。然而,满足查询需要对该索引进行完整扫描

其中一列或两列上的单列索引对于提高此查询的性能是无用的或更糟的

如果您必须让这个查询执行得很好,那么您需要稍微重新组织一下您的表。让我们想想。看起来您正试图排除“过期”记录:您想要
过期日期
。这是一个可搜索谓词

因此,如果您在表中添加了一个新列
expiration\u date
,然后将其设置为:

 UPDATE foo SET expiration_date = last_day + INTERVAL days DAY

然后对其进行索引,您将有一个性能良好的查询。

因为您在where条件中使用了一个表达式,mysql将无法对这两个字段中的任何一个使用索引。如果您经常使用这个表达式,并且至少有mysql v5.7.8,那么您可以创建一个表达式并在其上创建索引


另一个选项是创建一个正则列,并将其值设置为此表达式的结果,并为该列编制索引。您需要触发器来保持更新。

因为您在where条件中使用了一个表达式,mysql将无法对这两个字段中的任何一个使用索引。如果您经常使用这个表达式,并且至少有mysql v5.7.8,那么您可以创建一个表达式并在其上创建索引


另一个选项是创建一个正则列,并将其值设置为此表达式的结果,并为该列编制索引。您需要触发器来保持更新。

我不担心此表上的INSERT性能。主要是读取查询。我不担心这个表的插入性能。它主要是读取查询。因为您使用的是函数,所以最后一天不能用作索引。天数可以,但性能增益实际上取决于数据的方差。因为您使用的是函数,所以最后一天不能用作索引。天数可能会增加,但性能的提高实际上取决于数据的变化。这非常有用。谢谢,这真是太有帮助了。非常感谢。