Удаление записей из одной таблицы, соединенной с другой таблицей SQL - PullRequest
1 голос
/ 25 января 2020

У меня есть две таблицы: одна с 212 000 записей (устаревшие записи), а другая с 10 500 000 записей

Я хотел бы объединить две таблицы в полях id и version_number, поскольку обе таблицы имеют эти поля. Я надеялся, что из объединенной таблицы удастся удалить совпадающие записи (из объединенных таблиц), т.е. все 212 000 записей будут удалены из 10 500 000

. Мне было интересно, каков наилучший подход для этого, используя Oracle SQL? Я видел пример, где внутреннее соединение использовалось с использованием одного поля, а оператор удаления использовался для удаления таблицы 1 из таблицы 2, но не видел одно с двумя используемыми полями (в соединении).

Будет ли это смысл использовать внешнее объединение перед удалением записей? Я думал, что это может помочь мне отследить, что было удалено, если это возможно

Ответы [ 2 ]

2 голосов
/ 25 января 2020

Вам не нужно использовать OUTER JOIN за исключением проверки, сколько строк будет соотв. не будет удалено.

Пример такого запроса см. ниже (я использую сгенерированные тестовые данные, предоставленные в конце ответа)

with del as (
select delta.id, delta.version,
decode(big.id,null,0,1) is_deleted
from delta
left outer join big 
on delta.id = big.id and delta.version = big.version
)
select is_deleted, count(*) cnt, max(id||'.'||version) eg_id_vers
from del
group by is_deleted;

IS_DELETED        CNT  EG_ID_VERS                                                                   
---------- ---------- ----------
         1      20000 99995.0   
         0         20 100100.0   

С вашими данными Размер, который вы должны использовать HASH JOIN с full table scan для обеих таблиц, чтобы получить приемлемую производительность.

Существует два основных способа сделать DELETE

Обновляемый вид соединения.

Обратите внимание, что в этом случае ваша маленькая таблица должна иметь уникальный индекс на ID, VERSION (или первичный ключ)

create unique index delta_idx on delta(id,version);

Наоборот БОЛЬШОЙ таблица не должна иметь такого ограничения . Это важно, потому что ясно показывает, что ваша БОЛЬШАЯ таблица является единственной таблицей сохранения ключа в представлении соединения.

Просто поместите соединение в небольшой стол не может дублировать строки из большой таблицы из-за уникального ограничения

См. здесь дополнительная информация о Обновление представлений объединения

delete from 
(
select delta.id, delta.version, big.id big_id, big.version
from big 
join delta 
on delta.id = big.id and delta.version = big.version
)

Приведенное выше delete удаляет строки из таблицы BIG, поскольку это единственная таблица , сохраняющая ключи (см. Обсуждение выше)

Этот DML приводит к HASH JOIN

Удалить с помощью EXISTS

Если в вашем маленьком столе нет первичный ключ (т. е. он может содержать повторяющиеся строки с одинаковыми ID and VERSION), вы должны отступить к решению, предложенному в другой ответ .

DELETE FROM big 
    WHERE EXISTS (SELECT null
                  FROM delta
                  WHERE delta.id = big.id and delta.version = big.version
                 ) 

Нет индексов требуется, и вы должны ожидать план выполнения с HASH JOIN RIGHT SEMI, что означает, что оба подхода не отличаются друг от друга.

Пример данных для теста

create table big as
select 
trunc(rownum/10) id, mod(rownum,10) version,
lpad('x',10,'Y') pad
from dual connect by level <= 1000000;

/* the DELTA table has 50 times less rows,
allow some rows out of range of the BIG table - those rows will not be deleted **/
drop table delta;
create table delta as
select 
trunc(rownum*50/10) id, mod(rownum*50,10) version
from dual connect by level <= 1001000/50;

create unique index delta_idx on delta(id,version);
1 голос
/ 25 января 2020

В простом подходе просто используются IN или EXISTS:

DELETE FROM bigtable bt
    WHERE EXISTS (SELECT 1
                  FROM littletable lt
                  WHERE bt.? = lt.?
                 );

Требуется индекс на littletable для ключей, используемых для предложения корреляции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...