Оптимизировать время следующего запроса в 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;

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

3 ответа

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

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

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

Это должно ускорить not in часть запросов. Существует не способ обойти order by,

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

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,

Другие вопросы по тегам