Выполнение SQL-запроса занимает много времени - PullRequest
2 голосов
/ 15 июня 2011

У меня есть две таблицы.Таблицы 2 содержат более свежие записи.Таблица 1 содержит 900 тыс. Записей, а таблица 2 примерно такая же.

Выполнение запроса, указанного ниже, занимает около 10 минут.Большинство запросов (во время выполнения нижеприведенного запроса) к таблице 1 дают исключение тайм-аута.

    DELETE T1
    FROM Table1 T1 WITH(NOLOCK)
    LEFT OUTER JOIN Table2 T2
    ON T1.ID = T2.ID
    WHERE T2.ID IS NULL AND T1.ID IS NOT NULL

Может ли кто-нибудь помочь мне оптимизировать запрос выше или написать что-то более эффективное?Также, как решить проблему с тайм-аутом?

Ответы [ 3 ]

1 голос
/ 15 июня 2011

Оптимизатор, скорее всего, решит заблокировать всю таблицу, так как это проще сделать, если ему нужно удалить столько строк. В таком случае я удаляю кусками.

while(1 = 1)
begin
    with cte
    as
    (
        select *
        from Table1
        where Id not in (select Id from Table2)
    )
    delete top(1000) cte

    if @@rowcount = 0
        break

    waitfor delay '00:00:01' -- give it some rest :)
end

Таким образом, запрос удаляет 1000 строк за раз. Оптимизатор, скорее всего, заблокирует только страницу для удаления строк, а не всю таблицу.

Общее время выполнения этого запроса будет больше, но оно не будет блокировать других абонентов.

Отказ от ответственности: предполагается MS SQL.

Другой подход заключается в использовании SNAPSHOT транзакции. Таким образом, средства чтения таблиц не будут блокироваться во время удаления строк.

0 голосов
/ 15 июня 2011

Оба столбца идентификатора необходимо индекс

Тогда используйте более простой SQL

DELETE Table1 WHERE NOT EXISTS (SELECT * FROM Table2 WHERE Table1.ID = Table2.ID)
0 голосов
/ 15 июня 2011

Подождите секунду, вы пытаетесь сделать это ...

DELETE Table1 WHERE ID NOT IN (SELECT ID FROM Table2)

Если так, то я бы так написал. Вы также можете попробовать обновить статистику по обеим таблицам. И, конечно же, индексы Table1.ID и Table2.ID могут значительно ускорить процесс.

РЕДАКТИРОВАТЬ: Если вы получаете тайм-ауты от дизайнера, увеличьте значение тайм-аута «Дизайнер» в SSMS (по умолчанию 30 секунд). Сервис -> Параметры -> Дизайнеры -> «Переопределить значение времени ожидания строки подключения для обновлений дизайнера таблицы» -> введите разумное число (в секундах).

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