Mysql 联合优化与子查询

Mysql union optimization with subquery

我的问题是这个查询:

(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;

tableload_send_calc有18000条记录,temp有3000条table。查询本身需要 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

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

load_send_calc.temp_id
load_send_calc.active
temp.id_auto

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

相同的字段上进行了限制

3 件事可以加快速度:

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

IN ( SELECT ... ) 表现不佳,尤其是在旧版本的 MySQL 中。把它变成 JOIN.

给每个SELECT加一个LIMIT。例如:

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

内部的有所需最大值的限制 -- 外部的偏移量 + 限制。