【问题标题】:Speeding up mysql query加快mysql查询
【发布时间】:2013-03-29 01:40:10
【问题描述】:

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

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)

【问题讨论】:

  • 允许中断查询。
  • 你必须做索引。处理时间与您的系统无关。
  • hud.iduser_hud.hidusers.iduser_hud.uidhud.created_on 列上是否有索引?发布查询的EXPLAIN (dev.mysql.com/doc/refman/5.5/en/explain.html)。返回多少行,处理时间是多少?
  • @NathanBouscal 怎么样? where 与连接无关。
  • @NathanBouscal 不正确,查询优化器几乎总是足够聪明,可以自己解决这个问题。没有解释,这只是猜测。

标签: mysql


【解决方案1】:

hud.iduser_hud.hidusers.iduser_hud.uidhud.created_on 列上创建索引。

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

【讨论】:

    【解决方案2】:

    首先,您至少需要以下索引: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; 
    

    【讨论】:

    • 条件在hud,所以优化器应该只从hud中获取符合条件的记录,所以我认为这是不必要的。但是解释是唯一确定的方法。另外:FROM 中现在不是有 2 个表吗?我认为您的意思是仅从子查询中进行选择。
    • @dtech,不幸的是优化器不够智能,但你是对的,解释可能会有所启发。子查询中有两张表,不过这样应该没有问题,第二张只执行一次。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 2012-10-26
    • 2012-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多