SQL Server 2008: как NOLOCK работает для CTE? - PullRequest
1 голос
/ 05 января 2011

У меня есть CTE, которые все используют NOLOCK внутри. Но затем выбор из этих CTE в родительских CTE с использованием дочерних CTE не использует NOLOCK в предположении, что это уже NOLOCK. И окончательный выбор также не использует NOLOCK.

Примерно так:

with cte1 as
(select * from tab1 (nolock)),
cte2 as
(select * from cte1)

select * from cte2

или я напишу

with cte1 as
(select * from tab1 (nolock)),
cte2 as
(select * from cte1 (nolock))

select * from cte2 (nolock)

спасибо

Ответы [ 4 ]

4 голосов
/ 05 января 2011

Вам не нужна внешняя nolock, чтобы избежать общих блокировок на tab1. В этом легко убедиться, настроив трассировку SQL Profiler, фиксирующую различные события в категории locks, отфильтровав при этом скорость соединения SSMS и попробовав обе версии.

nolock - довольно опасная настройка, знаете ли вы обо всех возможных минусах его использования (грязное чтение, чтение данных дважды или нет вообще)?

2 голосов
/ 05 января 2011

NOLOCK для «внешнего» запроса также применяется к любым внутренним запросам. CTE - это просто макрос, подобный представлению или встроенной таблице udf: ни больше, ни меньше. Таким образом, вы на самом деле (игнорируя подсказки NOLOCK)

select * from (
               select * from (
                             select * from tab1
                             ) t1
               ) t2

С Таблица Советы по MSDN , в разделе «Примечания»

Все подсказки блокировки распространяются на все таблицы и представления, к которым обращается план запроса, включая таблицы и представления, на которые имеются ссылки в представлении.

В этом случае вам нужен только один. Не важно где.

Где это имеет значение, там, где у вас есть СОЕДИНЕНИЯ. Если бы cte1 был объединением 2 таблиц, он понадобился бы для каждой таблицы. Или укажите это один раз на более высоком / внешнем уровне.

О, и я присоединюсь ко всем остальным: NOLOCK - плохая идея

1 голос
/ 05 января 2011

Достаточно самого внутреннего nolock, нет необходимости повторять его для внешнего выбора.

Вы можете проверить это, начав транзакцию без ее завершения:

begin transaction
; with YourCte ( ...

Затем выможно просмотреть блокировки с помощью Management Studio.Они будут там, пока не истечет время транзакции.

0 голосов
/ 05 января 2011

NOLOCK для CTE работает так же, как и все остальное: это приводит к противоречивым результатам . Вместо этого используйте SNAPSHOT, см. Изоляция транзакций на основе управления версиями строк в SQL Server 2005 .

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