2016-12-01 17 views
0
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; 

По мере увеличения данных время запроса увеличивается. Пожалуйста, предоставьте решение для оптимизации времени, даже если данные продолжают растиоптимизировать следующее время запроса в sql

+1

В какой системе баз данных вы работаете? SQL Server, Oracle, MySQL и т. Д. –

+0

мой рабочий стол sql –

+1

Релевантная информация для вопросов оптимизации запросов включает текущий план запроса/оптимизатора, существующие индексы и приблизительные размеры таблиц. –

ответ

0

, так что вам нужны данные A + B - (пересечение B). Для этого вы используете 1 союз и 2 не в разделе. Я попытался устранить их в следующем запросе:

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), для чего вы можете использовать аналитическую функцию.

+0

Ограничение: 'OVER (PARTITION BY ...)' доступно только в MariaDB 10.2. –

0

Для вашего запроса, вы должны начать с индексами:

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

Это должно ускорить not in часть запросов. Нет никакого пути вокруг order by.

В общем случае использование подзапроса излишне налагает дополнительные затраты. Однако, поскольку вы используете order by, подзапрос, вероятно, не влияет на производительность.

+0

cn u plz написать точный запрос –

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.