2013-07-04 149 views
0

我有表结构像波纹管这么长的时间:MySQL查询需要在where子句

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 

我想知道哪些ITEM_ID是通过当前日期与大多数观点WHERE子句波纹管:

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子句和以年,月,日筛选?

================================== 编辑与讲解:

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  
+0

是什么'EXPLAIN'说? –

+0

表中有多少行? – Dmitry

+0

这是2,577,816行 –

回答

0

在表stats_item它真的有很多行。我尝试添加INDEX与创建,item_id结果仍然缓慢。

我使用的唯一方法是介于两者之间。这真是更好的,它的只花了0.0686秒的非常差,从4.1747秒

0

尝试添加复合索引:创建+ 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 
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 
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)