Oracle - Неверный реляционный оператор при использовании EXISTS - PullRequest
0 голосов
/ 01 мая 2020

У меня есть следующий запрос, который мне выдан, где возвращенная запись удаляется из таблицы et_fact_reclam_ter_his_mis c при выполнении условия:

DELETE FROM et_fact_reclam_ter_his_misc
 WHERE num_siniest || num_exped IN
 (SELECT DISTINCT num_siniest || num_exped
          FROM et_fact_reclam_ter_his_misc t1
         WHERE NOT EXISTS (SELECT *
                  FROM et_fact_reclam_ter_misc t2
                 WHERE t1.num_siniest = t2.num_siniest));

Я искал и нашел что использование EXISTS вместо IN улучшит производительность запросов. Но я столкнулся с 2 ошибками. Первое - это сообщение об ошибке, которое появляется, когда я заменяю оператор IN на EXISTS:

DELETE FROM et_fact_reclam_ter_his_misc
 WHERE num_siniest || num_exped EXISTS
 (SELECT DISTINCT num_siniest || num_exped
          FROM et_fact_reclam_ter_his_misc t1
         WHERE NOT EXISTS (SELECT *
                  FROM et_fact_reclam_ter_misc t2
                 WHERE t1.num_siniest = t2.num_siniest));


ORA-00920: invalid relational operator

Второе - когда я пытаюсь вложить SELECT в DELETE, но количество возвращаемых строк различно:

DELETE FROM et_fact_reclam_ter_his_misc
 WHERE EXISTS
 (SELECT FROM et_fact_reclam_ter_his_misc
         WHERE num_siniest || num_exped IN
               (SELECT DISTINCT num_siniest || num_exped
                  FROM et_fact_reclam_ter_his_misc t1
                 WHERE NOT EXISTS
                 (SELECT *
                          FROM et_fact_reclam_ter_misc t2
                         WHERE t1.num_siniest = t2.num_siniest)));

Я ценю любую помощь для улучшения производительности запросов

Ответы [ 2 ]

1 голос
/ 01 мая 2020

Не могли бы вы попробовать ниже, не самый лучший подход для объединения полей для объединений,

DELETE FROM et_fact_reclam_ter_his_misc A
 WHERE EXISTS
 (  SELECT 1 FROM 
         (SELECT DISTINCT num_siniest || num_exped
          FROM et_fact_reclam_ter_his_misc t1) B
          WHERE A.num_siniest|| A.num_exped = B.num_siniest || B.num_exped 
         AND NOT EXISTS (SELECT 1
                  FROM et_fact_reclam_ter_misc t2
                 WHERE B.num_siniest = t2.num_siniest));

Похоже, что объединенные столбцы являются числами, и это заставит oracle привести его к типу char, что может снизить производительность . Ниже следует быть быстрее, если вы имеете дело с большим количеством записей.

DELETE FROM et_fact_reclam_ter_his_misc A
 WHERE EXISTS
 (  SELECT 1 FROM 
         (SELECT DISTINCT num_siniest, num_exped
          FROM et_fact_reclam_ter_his_misc t1) B
          WHERE A.num_siniest = B.num_siniest
          AND  A.num_exped = B.num_exped 
         AND NOT EXISTS (SELECT 1
                  FROM et_fact_reclam_ter_misc t2
                 WHERE B.num_siniest = t2.num_siniest));

DISTINCT излишне убьет, подстановка group by определенно будет намного лучше, поэтому лучшим будет:

DELETE FROM et_fact_reclam_ter_his_misc A
 WHERE EXISTS
 (  SELECT 1 FROM 
         (SELECT num_siniest, num_exped,count(1)
          FROM et_fact_reclam_ter_his_misc t1
          group by num_siniest, num_exped) B
          WHERE A.num_siniest = B.num_siniest
          AND  A.num_exped = B.num_exped 
         AND NOT EXISTS (SELECT 1
                  FROM et_fact_reclam_ter_misc t2
                 WHERE B.num_siniest = t2.num_siniest));
0 голосов
/ 02 мая 2020

Похоже, что это может сделать это:

delete et_fact_reclam_ter_his_misc t1
where  not exists
       ( select * from et_fact_reclam_ter_misc t2
         where  t2.num_siniest = t1.num_siniest
       );

В исходной версии подзапрос первого уровня, кажется, запрашивает ту же самую таблицу, которая удаляется, просто для того, чтобы построить подзапрос not exists , Я подозреваю, что все, что вы хотите сделать, это удалить his строк, где num_siniest не существует в основной таблице. Некоторые примерные данные и ожидаемые результаты могут сделать это более ясным.

...