Избегайте дублирования при вставке данных в таблицу SQL Server без уникального столбца - PullRequest
0 голосов
/ 18 июня 2019

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

INSERT INTO archive (colA, colB, colC)
    SELECT
        colA, colB, colC
    FROM 
        dim.source src
    WHERE
        CONCAT(src.colA, src.colB, src.colC) NOT IN (SELECT CONCAT(colA, colB, colC) FROM archive)

Это работает, но, учитывая, что архив содержит> 40M строк, это довольно медленно (10+ минут).Есть ли более эффективные варианты?

Спасибо!

Я пробовал несколько других решений для stackoverflow, но они не работают для меня и приводят к сообщению об ошибке

Ответы [ 2 ]

0 голосов
/ 19 июня 2019

MySQL позволяет сравнивать кортежи, поэтому вам не нужен CONCAT:

WHERE (src.colA, src.colB, src.colC) NOT IN (SELECT colA, colB, colC FROM archive)

Такой тип использования функции исключает возможность использования любых индексов;но я не уверен, насколько эффективны сравнения кортежей, так что это может быть лучше:

LEFT JOIN archive AS a ON src.A = a.colA AND src.B = a.colB AND src.C = a.colC
WHERE a.archive_id IS NULL -- archive_id can be replaced with any field from archive you know would not be null if there were a match.

, и когда ни один из них не работает хорошо, вы всегда можете попробовать вместо этого коррелированный подзапрос:

WHERE NOT EXISTS (SELECT * FROM archive WHERE colA = src.A AND colB = src.B AND colC = src.C)
0 голосов
/ 18 июня 2019

В MySQL я бы предложил on duplicate key update:

create unique index unq_test_all on test(colA, colB, colC);

А затем:

insert into test (colA, colB, colC)
    select colA, colB, colC
    from dim.source s
    on duplicate key update colA = values(colA);
...