我的表格结构如下:
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秒
Bellow是表格中的索引
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进行过滤?
================================== 使用EXPLAIN编辑:
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 :(得分: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
答案 1 :(得分: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
答案 2 :(得分: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)
答案 3 :(得分:0)
在表stats_item中,它确实有很多行。我尝试使用created,item_id添加INDEX,结果仍然很慢。
我使用的唯一方法是介于两者之间。它真的更好,只需0.0686秒与4.1747秒非常不同