简体   繁体   English

在SQL中优化以下查询时间

[英]optimize the following query time in sql

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;

As the data is increasing the query time is increasing. 随着数据的增加,查询时间也在增加。 Please provide solution to optimize the time even if data keeps on increasing 即使数据持续增加,也请提供解决方案以优化时间

so you want data A + B -(a intersect B). 因此,您需要数据A + B-(与B相交)。 For that you are using 1 union and 2 not in clause. 为此,您使用1联合和2 not in子句。 I tried to eliminate those in following query: 我试图消除以下查询中的那些:

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

Basically first you should select all records using UNION ALL instead UNION. 基本上,首先应该使用UNION ALL而不是UNION选择所有记录。 after that filter out those records which appeared in both tables(tab1, tab2) for that you can use analytical function. 之后,筛选出出现在两个表(tab1,tab2)中的那些记录,以便您可以使用分析功能。

For your query, you should start with indexes: 对于查询,您应该从索引开始:

  • tab1(r.fa, r.date, r.status)
  • tab2(r.fa, r.date, r.status)

This should speed the not in portion of the queries. 这样可以加快查询中的“ not in部分。 There isn't a way around the order by . 没有办法解决order by

In general, using a subquery unnecessary imposes additional costs. 通常,不必要使用子查询会带来额外的费用。 However, because you are using order by , the subquery probably doesn't make a difference in terms of performance. 但是,由于您正在使用order by ,因此子查询可能不会对性能产生任何影响。

WHERE (a,b) ... has never been well optimized in MySQL. WHERE (a,b) ...在MySQL中从未进行过优化。 Avoid the construct. 避免构造。

IN ( SELECT ... ) has only recently been improved, but still it is not as good as EXISTS( SELECT * ...) or LEFT JOIN .. ON .. . IN ( SELECT ... )直到最近才得到改进,但是仍然不如EXISTS( SELECT * ...)LEFT JOIN .. ON .. Reformulate. 重新制定。

NOT IN , plus both of the above can be reformulated into LEFT JOIN ... ON ... WHERE ... IS NULL NOT IN ,加上以上两项都可以重新格式化为LEFT JOIN ... ON ... WHERE ... IS NULL

You don't need the outer SELECT , you can sort a UNION thus: 您不需要外部的SELECT ,因此可以对UNION进行排序:

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

Optionally the SELECTs could also have ORDER BY , but it is useful only(?) if you have a LIMIT . 可选地, SELECTs也可以具有ORDER BY ,但是只有当您具有LIMIT ,它才有用(?)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM