Удалить где не в запросе - PullRequest
0 голосов
/ 15 июня 2010

У меня есть справочная таблица (##lookup).Я знаю, что это плохой дизайн, потому что я дублирую данные, но это значительно ускоряет мои запросы.У меня есть запрос, который заполняет эту таблицу

insert into ##lookup select distinct col1,col2,... from table1...join...etc...

Я хотел бы смоделировать это поведение:

delete from ##lookup
insert into ##lookup select distinct col1,col2,... from table1...join...etc...

Это явно обновит таблицу правильно.Но это много вставки и удаления.Он портится с моими индексами и блокирует таблицу для выбора.

Эта таблица также может быть обновлена ​​чем-то вроде:

delete from ##lookup where not in (select distinct col1,col2,... from table1...join...etc...)
insert into ##lookup (select distinct col1,col2,... from table1...join...etc...) except if it is already in the table

Второй способ может занять больше времени, но я могу сказать,«без блокировки», и я смогу выбрать из таблицы.

Есть идеи, как написать запрос вторым способом?

Ответы [ 2 ]

2 голосов
/ 15 июня 2010
DELETE LU
FROM ##lookup LU
LEFT OUTER JOIN Table1 T1 ON T1.my_pk = LU.my_pk
WHERE T1.my_pk IS NULL

INSERT INTO ##lookup (my_pk, col1, col2...)
SELECT T1.my_pk, T1.col1, T1.col2...
FROM Table1 T1
LEFT OUTER JOIN ##lookup LU ON LU.my_pk = T1.my_pk
WHERE LU.my_pk IS NULL

Вы также можете использовать WHERE NOT EXISTS вместо левых соединений выше для поиска несуществования строк.

Возможно, вы захотите взглянуть на оператор MERGE, если вы используете SQL 2008. В противном случае вы не будете синхронизировать таблицы - вы будете синхронизировать только PK. Если один из столбцов изменяется в одной таблице, но не другой, это не будет отражено выше.

В любом случае, может показаться, что вы захотите оптимизировать запросы. Хотя дублирование данных может показаться хорошим решением проблем с производительностью, вы можете видеть, что это может повлечь за собой множество головных болей (и это только один из них). Вам лучше найти причину плохой работы и устранить ее, чем надеть эту уродливую повязку.

0 голосов
/ 20 июня 2010

Все DELETE регистрируются, что снижает производительность, если вы планируете уничтожить всю таблицу. В зависимости от количества строк, с которыми вы имеете дело, вы можете использовать незарегистрированный TRUNCATE.

Сколько времени занимает утверждение SELECT? Вы можете попробовать что-то вроде этого, если выбор занимает небольшое количество времени, и вы не запускаете его часто.

выберите отличное ... INTO # tempTable1 из таблицы1 ... присоединиться ... и т.д ...

начать транзакцию удалить таблицу ## поиск выберите * в ## lookup from # tempTable1 совершить транзакцию

Ответ Тома, пожалуй, самый надежный, но я просто подумал, что я должен вмешаться с некоторыми альтернативами. Не уверен, зачем нужна глобальная временная таблица по сравнению с реальной таблицей ???

...