Какой самый быстрый способ обнаружить несовпадающие записи между двумя таблицами? - PullRequest
1 голос
/ 02 января 2012

Я пытаюсь обнаружить несколько неработающих записей в базе данных MS-SQL.

В упрощенном примере сценарий таков:

У меня есть 2 таблицы, проще говоря:

  • Таблица_1: идентификатор, дата, идентификатор операции

  • Таблица_2: дата, идентификатор операции, имя события

И у меня есть это бизнес-правило: если в Таблице_1 есть запись, ТОГДА в Таблице_2 должна быть хотя бы одна строка для Таблицы_1. Дата и Таблица.OpId.

Если в Таблице_1 есть строка и если в Таблице_2 нет строки, совпадающей с этой строкой, ТО есть поврежденные данные - независимо от причины.

Чтобы узнать неверные данные, я использую:

SELECT *
FROM table_1 t1
LEFT JOIN table_2 t2 ON t1.Date = t2.Date AND t1.OpId = t2.OpId
WHERE t2.OpId IS NULL -- So, if there is no 
--                           matching row in table_2 then this is a mistake

Но для завершения запроса требуется слишком много времени.

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

Ответы [ 2 ]

6 голосов
/ 02 января 2012

Чтобы сделать анти-полусоединение NOT EXISTS в SQL Server, обычно лучше или равно по производительности другие параметры (NOT IN, OUTER JOIN ... NULL, EXCEPT)

SELECT *
FROM   table_1 t1
WHERE  NOT EXISTS (SELECT *
                   FROM   table_2 t2
                   WHERE  t1.Date = t2.Date
                          AND t1.OpId = t2.OpId) 

См левое внешнее соединение против НЕ СУЩЕСТВУЕТ .Возможно, вам не хватает полезного индекса.

1 голос
/ 02 января 2012

Если вы используете правильное индексирование, это не имеет никакого отношения (возможно, использование NOT EXISTS вместо LEFT JOIN будет немного быстрее),

НО

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

SELECT table_1.*
INTO tempTable
FROM table_1 t1
WHERE EXISTS(SELECT * FROM table_1 t1 WHERE t1.Date = t2.Date AND t1.OpId = t2.OpId)

drop table Table_1

exec sp_rename 'tempTable', 'Table_1'

Это может быть быстрее

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