У меня есть сценарий, в котором данные клиентов создаются в одной схеме и передаются в другую схему для бизнес-операций. В некоторых случаях данные не передаются, поэтому я использую приведенный ниже запрос для определения отсутствующих данных. Но он продолжает работать, не возвращая данные, поскольку в обеих таблицах более 5 миллионов записей. Как оптимизировать и получить результат?
SELECT CUSTID FROM SCHEMA1.CUSTOMER WHERE CUSTID NOT IN(SELECT ID FROM SCHEMA2.CUST_TBL);
После добавления еще одного фильтра ответ на запрос остается таким же.
SELECT CUSTID FROM SCHEMA1.CUSTOMER WHERE CUSTID NOT IN(SELECT ID FROM SCHEMA2.CUST_TBL WHERE CUST_TYPE=0);
CUSTID и ID являются индексированными, уникальными и ненулевыми столбцами. CUST_TYPE не равно null, но не индексировано.
Также пробовал с /*+parallel(50)*/
Версия Oracle: 19c
В зависимости от вашей версии Oracle,
not in (subquery)
может быть проблемой, когдаcustid
илиid
являются столбцами, допускающими значение NULL. Если это так, вы можете попробовать добавитьwhere id is not null
во внутренний запрос (при условии, что ни один столбец не нуждается в уточнении имени таблицы) или переписать его какnot exists
. Кроме того,parallel(50)
является чрезмерным. Я бы начал с простогоparallel
и предоставил решение Oracle.На самом деле, теперь, когда я проверяю (например, здесь), анти-соединение с нулевым значением было добавлено еще в 11g, поэтому, вероятно, столбец, допускающий значение NULL, не является проблемой в вашем случае. Если бы вы могли поделиться планом выполнения и вашей версией Oracle, это было бы полезно.
поля id и custid являются обязательными и индексируемыми полями. Использование версии Oracle 19c
передача еще одного фильтра cust_type во внутренний запрос, который также не является нулевым столбцом. ВЫБЕРИТЕ CUSTID ИЗ SCHEMA1.CUSTOMER A, ГДЕ CUSTID НЕ ВХОДИТ (ВЫБЕРИТЕ ID ИЗ SCHEMA2.CUST_TBL B и B.cust_type=0 );
Я думаю, что в обновленной версии отсутствует ключевое слово
where
. Но в любом случае план выполнения был бы полезен вместе с более подробными цифрами. Сколько строк возвращает запрос? Сколько строк возвращает измененный подзапрос?да, это
where
. пересмотренный подзапрос возвращает около 3,5 млн записей и проверяет 5 млн записей. при использовании запроса bobC() для возврата результатов требуется около 380 секунд.select custid from SCHEMA1.CUSTOMER c1 left join SCHEMA2.CUST_TBL c2 on c1.custid = c2.id where c2.id is null and c2.CUST_TYPE=0
;Необходимо проверить 5 М строк, чтобы убедиться, что они не входят в набор из 3,5 М строк. Индексы тут не помогут и, скорее всего, сделают его медленнее. Если это то, что происходит, это должно быть ясно из плана выполнения. Вы пробовали метод MINUS Литтлфута?
Да, это помогает. Спасибо, Уильям