使用子查询进行Mysql联合优化

时间:2015-04-16 10:08:05

标签: mysql optimization limit union

我的问题是这个查询:

(SELECT    
     ID1,ID2,ID3,ID4,ID5,ID10,ID11,ID13,ID14,ID454,ID453,
     TIME,TEMP_ID,'ID_AUTO',PREDAJCA,VYTVORIL,MAIL,TEMP_ID_HASH,ID_SEND 
   FROM `load_send_calc` 
   WHERE `TEMP_ID` LIKE '$find%' 
     AND ACTIVE = 1 AND TEMP_ID > 0)
UNION ALL
(SELECT 
     ID1,ID2,ID3,ID4,ID5,ID10,ID11,ID13,ID14,ID454,ID453,TIME,'',
     ID_AUTO,'','','','','' 
  FROM `temp` 
  WHERE `ID_AUTO` LIKE '$find%' 
    AND `ID_AUTO` NOT IN (SELECT TEMP_ID 
                            FROM `load_send_calc` 
                            WHERE `load_send_calc`.ACTIVE = 1)
)
ORDER BY TIME  DESC LIMIT $limitFrom,$limitTo;

load_send_calc和3000表temp中有18000条记录。查询本身需要超过2分钟才能执行。有没有办法优化这个时间?

我已经尝试将顺序放入每个子查询中,但它没有显着帮助。我非常绝望,所以我真的很感激任何帮助。

编辑: 这是EXPLAIN结果:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY load_send_calc  ALL NULL    NULL    NULL    NULL    18394   Using where
2   UNION   temp    ALL NULL    NULL    NULL    NULL    1918    Using where
3   DEPENDENT SUBQUERY  load_send_calc  ALL NULL    NULL    NULL    NULL    18394   Using where
NULL    UNION RESULT    <union1,2>  ALL NULL    NULL    NULL    NULL    NULL    Using filesort

2 个答案:

答案 0 :(得分:2)

感谢您添加解释输出 - 它告诉了我们很多。查询不使用单个索引,这对性能非常不利。一个非常简单的优化是在join以及where子句中使用的字段上添加索引。在您的情况下,这些字段将是:

load_send_calc.temp_id
load_send_calc.active
temp.id_auto

除此之外,您还有一个不必要的AND TEMP_ID > 0,因为您已使用WHERE TEMP_ID LIKE '$find%'

限制同一字段

答案 1 :(得分:2)

要加快速度的三件事:

INDEX(active, temp_id) -- significantly better than two separate indexes

IN ( SELECT ... )表现不佳,特别是在旧版本的MySQL中。将其变为JOIN

为每个LIMIT添加SELECT。例如:

( SELECT ... ORDER BY ... LIMIT 80 )
UNION ALL
( SELECT ... ORDER BY ... LIMIT 80 )
             ORDER BY ... LIMIT 70, 10;

内部的最大限度需要 - 外部的偏移+限制。