У меня есть процесс с Select, который занимает много времени, порядка 5-10 минут.
В настоящее время я не использую NOLOCK в качестве подсказки для механизма базы данных MS SQL.
В то же время у нас есть другой процесс, выполняющий обновления и вставки в ту же базу данных и те же таблицы.
Первый процесс начался, недавно закончился преждевременно с сообщением
SQLEXCEPTION: транзакция была заблокирована для ресурсов блокировки с другим процессом и была выбрана в качестве жертвы взаимоблокировки.
Этот первый процесс выполняется на других сайтах в идентичных условиях, но с меньшими базами данных, и, таким образом, рассматриваемый оператор select занимает гораздо более короткий период времени (порядка 30 секунд или около того). На этих других сайтах я не получаю сообщения о тупике на этих других сайтах. Я также не получил этого сообщения на сайте, на котором изначально возникла проблема, но, как я полагаю, по мере роста базы данных я полагаю, что я, должно быть, преодолел некоторый порог. Вот мои вопросы:
- Может ли время, необходимое для выполнения транзакции, повысить вероятность того, что связанный процесс будет отмечен как жертва тупика.
- Если я выполню выбор с подсказкой NOLOCK, устранит ли это проблему?
- Я подозреваю, что поле datetime, которое проверяется как часть предложения WHERE в операторе select, вызывает медленное время поиска. Могу ли я создать индекс на основе этого поля? Это целесообразно?
источник
Ответы:
Нет. SELECT является жертвой, потому что он имел только считанные данные, поэтому транзакция имеет более низкую стоимость, поэтому она выбрана в качестве жертвы:
Нет. По нескольким причинам:
Наверное. Причиной тупика почти очень вероятно, будет плохо индексируются database.10 минут запросы являются приемлемыми в таких стесненных условиях, что я 100% уверен в вашем случае это не приемлемо.
С вероятностью 99% я заявляю, что ваша тупиковая ситуация вызвана конфликтом сканирования большой таблицы с обновлениями. Начните с захвата графика тупиковых ситуаций, чтобы проанализировать причину. Скорее всего, вам придется оптимизировать схему своей базы данных. Прежде чем вносить какие-либо изменения, прочтите этот раздел « Проектирование индексов» и подстатьи .
источник
Вот как на самом деле возникла эта конкретная проблема с тупиком и как она была решена. Это довольно активная база данных, ежедневно происходит 130 000 транзакций. Индексы в таблицах этой базы данных изначально были кластеризованы. Клиент попросил нас сделать индексы некластеризованными. Как только мы это сделали, начался тупик. Когда мы восстановили кластерные индексы, взаимоблокировка прекратилась.
источник
Ответы здесь стоит попробовать, но вам также следует проверить свой код. В частности, прочитайте ответ Polyfun здесь: Как избавиться от тупика в приложении SQL Server 2005 и C #?
В нем объясняется проблема параллелизма и то, как использование «with (updlock)» в ваших запросах может исправить вашу ситуацию взаимоблокировки - в зависимости от того, что именно делает ваш код. Если ваш код действительно следует этому шаблону, это, вероятно, лучше исправить, прежде чем прибегать к грязному чтению и т. Д.
источник
Хотя @ Remus Rusanu уже является отличным ответом, на случай, если кто-то с нетерпением ждет более глубокого понимания причин тупиковых ситуаций и стратегий трассировки SQL Server , я бы посоветовал вам прочитать книгу Брэда МакГихи « Как отследить взаимоблокировки с помощью SQL Server 2005 Profiler»
источник