2013-04-06 74 views
0

所以我在这里有一个基本的查询选择日期范围。它似乎需要(相对较长的时间来处理)我想知道我能做些什么来改善处理时间。这是查询。加速mysql查询

SELECT h.id as hid,h.created_on,u.id as uid,u.fname,u.lname,u.email 
FROM hud h 
LEFT JOIN user_hud uh on h.id = uh.hid 
LEFT JOIN users u on u.id = uh.uid 
WHERE 
    h.created_on 
    BETWEEN DATE_SUB(CURDATE() ,INTERVAL 12 MONTH) 
     AND DATE_SUB(CURDATE() ,INTERVAL 7 DAY) 
+0

打破了查询是允许的。 – GolezTrol 2013-04-06 18:05:43

+0

'解释',任何人? – raina77ow 2013-04-06 18:07:05

+1

你在'''hud.id''','''user_hud.hid''','users.id''','user_hud.uid''和'''hud .created_on'''列?发布查询的“EXPLAIN”(http://dev.mysql.com/doc/refman/5.5/en/explain.html)。返回多少行,处理时间是多少? – dtech 2013-04-06 18:07:19

回答

1

hud.iduser_hud.hidusers.iduser_hud.uidhud.created_on列制作的索引。

没有索引需要检查整个表的加入。使用索引,您可以使用更高效的方法(以更新/删除性能损失和更多磁盘空间为代价)

0

首先,您至少需要以下索引:hud中的(created_on),user_hud中的(hid)。然后,你可以看看你的查询,并意识到你的条件是在第一个表中您的加入,让你可以移动到条件的子查询:

SELECT hids.*, u.id as uid, u.fname, 
      u.lname, u.email 
FROM (
    SELECT id as hid, created_on 
    FROM hud, 
     (SELECT DATE_SUB(CURDATE() ,INTERVAL 12 MONTH) as year_ago, 
        DATE_SUB(CURDATE() ,INTERVAL 7 DAY) as week_ago) d 
    WHERE created_on BETWEEN year_ago AND week_ago 
    ) as hids 
LEFT JOIN user_hud uh USING(hid) 
LEFT JOIN users u on u.id = uh.uid; 
+0

这个条件是在'''hud'''上,所以优化器应该只从hud获得符合条件的记录,所以我认为这是不必要的。但是解释是唯一可以确定的方法。另外:现在在'''FROM'''里没有2个表吗?我想你的意思是只从子查询中选择。 – dtech 2013-04-06 18:49:16

+0

@dtech,不幸的是,优化器不够好,但是你说得对,解释可能会说明问题。子查询中有两个表,但这应该没有问题,第二个只执行一次。 – newtover 2013-04-06 19:03:45