Показать сообщение отдельно
Старый 31.01.2019, 12:37   #2  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,892 / 5650 (194) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Я просто добавлю, что update_recordset (точнее говоря - update в SQL Server) вешает блокировки не только на те записи, которые он реально обновляет, но и на те записи, которые попали в выборку по индексу. Ну то есть - если у нас подходящего индекса нету, то SQL может попробовать поискать по какому-то случайному индексу по dataAreaId, а перед поиском - попробуем все это ненадолго заблокировать. Плюс - иногда SQL Server переглючивает или индексы фрагментируются или еще что-то подобное случается, и оно выбирает план исполнения по не тому индексу. В этом случае тоже случаются аналогичные блокировки.

В то же время, если нам надо обновить не 100-200, а эдак 100K-200K записей, то особой альтернативы update_recordset просто нету. Да - есть вероятность блокировок. Да - надо строить правильные индексы. Да надо регулярно их перестраивать и строить статистику. Да -есть вероятность время от времени нарваться на блокировки. Но просто в каждом конкретном случае мы должны сравнивать риски больших задержек из за пошагового обновления и риски задержек из за взаимных блокировок.
Плюс - я не уверен что во всех сценариях мы можем создавать отдельную транзакцию на каждое обновление. При этом если у нас одна большая транзация и обновление идет по одной записи в while select forupdate, то порядок обновления в разных кусках кода вполне может быть разным. (К слову сказать - в исходном примере вообще в while select не стоит order by, соответственно порядок обновления записей не является гарантированым...)

Последний раз редактировалось fed; 31.01.2019 в 12:53.
За это сообщение автора поблагодарили: mazzy (2), trud (5), Logger (5).