0

我有如下表结构:

id item_id created
1  5       2012-09-05 09:37:59
2  5       2012-09-05 10:25:09
3  5       2012-09-05 11:05:09
4  1       2012-09-05 10:25:09
5  3       2012-09-05 03:05:01

我想通过 WHERE 子句通过当前日期知道哪个 item_id 是最受关注的,如下所示:

SELECT item_id, COUNT( id ) AS TOTAL
FROM stats_item
WHERE DAY( created ) =  '05'
AND MONTH( created ) =  '07'
AND YEAR( created ) =  '2013'
GROUP BY item_id
ORDER BY TOTAL DESC 
LIMIT 0 , 30

MySql 中的结果查询

Showing rows 0 - 29 ( 30 total, Query took 4.1747 sec)

耗时长达 4.1747 秒

波纹管是表中的索引

Table        Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
stats_item   0          PRIMARY  1            id          A         2575580     NULL     NULL         BTREE
stats_item   1          created  1            created     A          515116     NULL     NULL   YES   BTREE

为什么使用 WHERE 子句查询需要这么长时间并使用 YEAR、MONTH 和 DAY 进行过滤?

=================================== 用解释编辑:

Field   Type                Null Key    Default Extra
id      int(11) unsigned    NO   PRI    NULL    auto_increment
item_id int(11) unsigned    YES         NULL    
created timestamp           YES  MUL    NULL    
4

4 回答 4

0

尝试添加复合索引:created+item_id
尝试使用如下查询:

SELECT item_id, COUNT( id ) AS TOTAL FROM stats_item
WHERE created >= "2013-07-05" and created <= "2013-07-05 23:59:59" 
GROUP BY item_id ORDER BY TOTAL DESC LIMIT 0 , 30
于 2013-07-04T02:25:33.297 回答
0

试试这个。我打赌它跑得更快。当您在日期上使用函数时,引擎通常会忽略索引。将范围直接与日期字段进行比较应该更快。

SELECT   item_id, COUNT( id ) AS TOTAL
FROM     stats_item
WHERE    created BETWEEN '2013-05-07' AND '2013-05-07 23:59:59'
GROUP BY item_id
ORDER BY TOTAL DESC 
LIMIT 0, 30
于 2013-07-04T02:25:41.370 回答
0

什么需要很长时间?两个可能的原因。一是表正在执行全表扫描(因为where子句中的函数排除了索引的使用)。另一个是因为有很多很多行。

第一个问题由JW的解决方案解决:

WHERE   created >= '2013-07-05' AND
        created < '2013-07-05' + INTERVAL 1 DAY

没有函数的直接比较应该始终使用索引。

因为这不是问题,所以让我假设一天有很多很多行。如果是这样,则问题是索引可能发生的称为抖动的问题。这基本上意味着每个匹配的参考文献都在不同的页面上,因此您仍然需要阅读大量页面。解决这个问题的方法是添加item_id到索引中。在create table声明中,您将执行以下操作:

index (created, item_id)

或者你会这样做:

create index stats_item_created_item_id on stats_item(created, item_id)
于 2013-07-04T02:28:23.950 回答
0

在表 stats_item 中确实有很多行。我尝试使用 created, item_id 添加 INDEX 结果仍然很慢。

我使用的唯一方法是介于两者之间。真的更好,它只用了 0.0686 秒,与 4.1747 秒相差很大

于 2013-07-04T03:42:11.223 回答