在sql

时间:2016-12-01 09:28:12

标签: mysql sql query-optimization workbench

select *
from ((select 'Temp', r.*
       from tab1 r 
       where (r.fa, r.date, r.status) not in (select r1.fa, r1.date, r1.status from tab2 r1)
      ) union all
      (select 'report', r.* 
       from tab2 r 
       where (r.fa, r.date, r.status) not in (select r1.fa, r1.date, r1.status from tab1 r1)
      )
     ) temp
order by fa;

随着数据的增加,查询时间也在增加。即使数据不断增加,也请提供优化时间的解决方案

3 个答案:

答案 0 :(得分:0)

所以你想要数据A + B - (一个交叉点B)。为此你使用1个union而2个不在in子句中。我试图消除以下查询中的那些:

SELECT *
FROM(
SELECT X.*, COUNT(DISTINCT CN) OVER(PARTITION BY r.fa,r.date,r.status) CNT
FROM (
SELECT  'Temp' CN,r.* 
FROM    tab1 r 
UNION ALL
SELECT  'report' CN,r.* 
FROM    tab2 r 
)X)Y
WHERE Y.CNT=1

首先,您应首先使用UNION ALL而不是UNION选择所有记录。之后筛选出两个表(tab1,tab2)中出现的那些记录,你可以使用分析函数。

答案 1 :(得分:0)

对于您的查询,您应该从索引开始:

  • @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], host: { '(window:resize)': 'onResize($event)' } }) export class AppComponent{ onResize(event){ event.target.innerWidth; // window width } }
  • tab1(r.fa, r.date, r.status)

这应该加快查询的tab2(r.fa, r.date, r.status)部分。围绕not in没有办法。

通常,使用不必要的子查询会产生额外的成本。但是,因为您使用的是order by,所以子查询可能在性能方面没有区别。

答案 2 :(得分:0)

WHERE (a,b) ...从未在MySQL中得到很好的优化。避免构造。

IN ( SELECT ... )最近才得到改善,但仍不如EXISTS( SELECT * ...)LEFT JOIN .. ON ..。重新配制。

NOT IN,以上两个都可以重新制定为LEFT JOIN ... ON ... WHERE ... IS NULL

您不需要外部SELECT,因此您可以对UNION进行排序:

( SELECT ... )
UNION ALL
( SELECT ... )
ORDER BY ...    -- applies to UNION

可选SELECTs也可以ORDER BY,但如果你有LIMIT,它只有用(?)。