2015-09-23 2 views
0

У меня есть таблица, которая часто читает, вставляет & обновления (она содержит данные сеанса пользователя сайта). Он имеет кластеризованный индекс в поле varchar, называемом sessionID.Удалите несколько строк из таблицы с частыми чтениями и записью

Мне нужно удалить кучу записей по списку sessionID s в другой таблице. Когда я пытаюсь удалить большое количество из них за раз, создается блокировка, которая предотвращает запись и чтение таблицы.

Если я удаляю их по очереди с использованием цикла foreach в пакете SSIS, он, похоже, устраняет блокировку.

Есть ли возможные долгосрочные негативные последствия для удаления строк за строкой?

+0

С помощью метода, который, как вы говорите, работает, он отменяет блокировку? если это так, вы можете получить грязные данные от чтения данных, которые еще не были зафиксированы. Это, конечно, зависит от того, как вы удаляете данные. – Dane

+2

Не уверен, но это может привести к быстрому увеличению вашего файла журнала. Я думаю, вам не нужно удалять по строке, лучше выяснить размер блока, где блокировка не повредит другим действиям и [удалить в кусках] (http://sqlperformance.com/2013/03/io-subsystem/chunk -deletes). – DrCopyPaste

+0

спасибо @DrCopyPaste, это полезная ссылка. Я выполнил тест, чтобы удалить 5000 записей подряд за строкой, и журнал транзакций не увеличился вообще. (простая модель восстановления). В настоящее время мы удаляем куски 5000 одновременно, создавая блокировки. – jessieloo

ответ

1

Итак, это вопрос о блокировке вкладок, блокировок страниц и блокировок строк. Случается, что вы удаляете несколько страниц, поэтому sql блокирует всю таблицу. Обычно Sql использует одну блокировку для каждой транзакции, поэтому он выбирает наименьшую блокировку, которая охватывает все затронутые строки. Удалите одну строку, и она будет использовать блокировку строк, удалить несколько последовательных записей и использовать блокировку страницы, удалить записи из нескольких страниц и заблокировать всю таблицу.

С varchar как ПК и сгруппированным индексом вы вряд ли когда-либо ударите блокировку страницы, потому что порядок, который записи отображаются в таблице, случайный (больше о том, почему это очень нежелательно в минуту). Таким образом, ваш выбор - блокировки строк или блокировки вкладок, поскольку блокировка таблицы не является опцией, блокировка строк - ваш единственный выбор.

Что касается плохих эффектов, то есть проблема журнала транзакций, упомянутая drcopypaste, но есть намного худшая проблема, если ваш ПК/кластер не является последовательным. Если он не является последовательным каждый раз, когда вы вставляете запись или удаляете запись, БД должна переместить все последующие записи, поскольку кластеризованный индекс (который почти всегда находится в таблице pk) состоит в том, как строки физически сортируются по таблице ,

+0

спасибо, так что это звучит как строка за строкой - это единственный вариант, но в идеале мы хотим создать другую таблицу с идентификатором в качестве первичного ключа, а затем индекс на sessionID? – jessieloo

+0

Зависит от того, является ли ваш PK (varchar) последовательным, если это тогда, это не слишком большая сделка (она делает индексы огромными и замедляет любые чтения, но не так уж и плохо), если это не так, вы можете добавить столбец идентификатора к таблице, переключите кластеризованное и pk на это и уменьшите диск IO, необходимый для изменений этой таблицы на порядок или больше. – Randall

Смежные вопросы