Mysql 有效地将SQL搜索限制在过去3个月内

Mysql 有效地将SQL搜索限制在过去3个月内,mysql,sql,Mysql,Sql,我有一张十年前的唱片清单。我正在寻找25个最新的条目,其中包括一个单词。当没有25个条目时,问题就出现了,查询需要很长的时间才能完成,因为它会遍历多年前的每条记录 执行查询以限制列表似乎效率低下,因为大多数查询的结果远远超过25个 我正在努力寻找最有效的方法来解决这个问题 我目前的工作内容: SELECT pk, title, time_item FROM list WHERE title LIKE '%word%' AND time_item > UNIX_TIMESTAMP() -

我有一张十年前的唱片清单。我正在寻找25个最新的条目,其中包括一个单词。当没有25个条目时,问题就出现了,查询需要很长的时间才能完成,因为它会遍历多年前的每条记录

执行查询以限制列表似乎效率低下,因为大多数查询的结果远远超过25个

我正在努力寻找最有效的方法来解决这个问题

我目前的工作内容:

SELECT pk, title, time_item 
FROM list 
WHERE title LIKE '%word%' AND time_item > UNIX_TIMESTAMP() - 60*60*24*90 
ORDER BY pk DESC
LIMIT 25;

您的查询看起来不错,但您可以通过使用介于 开始和现在:

SELECT pk, title, time_item 
FROM list 
WHERE title LIKE '%word%'
AND time_item between UNIX_TIMESTAMP() - 60*60*24*90 and UNIX_TIMESTAMP()
ORDER BY pk DESC
LIMIT 25
优化器可以在索引上使用范围,但不能使用开放条件


当然,您应该在
time\u项上有一个索引

您的查询看起来不错,但是您可以通过使用介于 开始和现在:

SELECT pk, title, time_item 
FROM list 
WHERE title LIKE '%word%'
AND time_item between UNIX_TIMESTAMP() - 60*60*24*90 and UNIX_TIMESTAMP()
ORDER BY pk DESC
LIMIT 25
优化器可以在索引上使用范围,但不能使用开放条件

当然,对于此查询,您应该在
time\u项上有一个索引

SELECT pk, title, time_item 
FROM list 
WHERE title LIKE '%word%' AND time_item > UNIX_TIMESTAMP() - 60*60*24*90 
ORDER BY pk DESC
LIMIT 25;
唯一有帮助的索引是
(时间项)
(时间、标题)
(这包括
where
子句)。或者,如果您确实有很多数据,您可能希望按
time\u项
进行分区

你必须在所有标题中搜索“单词”。如果这确实是一个基于单词的文本搜索,那么您可能会发现它更适合筛选标题

也就是说,如果性能问题是您有大量与条件匹配的数据,并且需要对所有数据进行排序,那么您可以做的就很少了。

对于此查询:

SELECT pk, title, time_item 
FROM list 
WHERE title LIKE '%word%' AND time_item > UNIX_TIMESTAMP() - 60*60*24*90 
ORDER BY pk DESC
LIMIT 25;
唯一有帮助的索引是
(时间项)
(时间、标题)
(这包括
where
子句)。或者,如果您确实有很多数据,您可能希望按
time\u项
进行分区

你必须在所有标题中搜索“单词”。如果这确实是一个基于单词的文本搜索,那么您可能会发现它更适合筛选标题


这就是说,如果性能问题是您有大量与条件匹配的数据,并且需要对所有数据进行排序,那么您所能做的就很少了。

通过切换WHERE查询的顺序(将时间搜索放在标题搜索之前),我可以节省大约1/3的时间

然后,我可以在90天前找到一个项目的主键,并将其用作查询参数,而不是time_add,从而节省更多

SELECT pk, title, time_item 
FROM articles
WHERE pk > (SELECT MIN(pk) FROM articles WHERE time_item > UNIX_TIMESTAMP() - 60*60*24*90) AND title LIKE '%word%'
ORDER BY pk DESC 
LIMIT 25

这些更改,通过添加时间项索引,将查询时间缩短到所需时间的1/6左右。

通过切换WHERE查询的顺序,我可以节省大约1/3的时间(时间搜索在标题搜索之前)

然后,我可以在90天前找到一个项目的主键,并将其用作查询参数,而不是time_add,从而节省更多

SELECT pk, title, time_item 
FROM articles
WHERE pk > (SELECT MIN(pk) FROM articles WHERE time_item > UNIX_TIMESTAMP() - 60*60*24*90) AND title LIKE '%word%'
ORDER BY pk DESC 
LIMIT 25

通过添加时间项索引,这些更改将查询时间缩短到所需时间的1/6左右。

谢谢,尝试过了。还是一样慢。问题似乎是它正在检查每一条记录,看它是否在日期范围内。@bbrodsky请尝试以下操作:
分析表列表
,然后重试query@Bohemian . . . 我不明白为什么优化器会对
之间的
使用范围扫描,但对>不使用范围扫描。我想我没见过。谢谢,试过了。还是一样慢。问题似乎是它正在检查每一条记录,看它是否在日期范围内。@bbrodsky请尝试以下操作:
分析表列表
,然后重试query@Bohemian . . . 我不明白为什么优化器会对
之间的
使用范围扫描,但对>不使用范围扫描。我想我还没见过。你已经试过使用窗口函数了吗?@Sujitmohanty30问题是,大多数查询很快就填满了25的限制,所以我认为这会降低大多数查询的速度。字符串开头的通配符会降低性能。你试过全文索引吗?@草莓,即使去掉通配符也只会有一点帮助。查询时间仍然太长,因为它仍在搜索数百万条旧记录。您是否已经尝试使用窗口函数?@Sujitmohanty30问题是,大多数查询很快就超过了25条的限制,因此我认为这会降低大多数查询的速度。字符串开头的通配符会降低性能。你试过全文索引吗?@草莓,即使去掉通配符也只会有一点帮助。查询仍然需要花费太长时间,因为它仍然搜索数百万条旧记录。