nolock во временной таблице в SQL Server 2008
не добавлять with (Nolock)
уменьшить конкуренцию при выборе из временных таблиц или SQL Server достаточно умен, чтобы не создавать конкуренцию на временных таблицах в первую очередь?
PS: Да, я знаю об опасностях READUNCOMMITTED.
select * from #myTempTable
vs
select * from #myTempTable with (nolock) --is this faster?
3 ответов
вы можете использовать флаг трассировки 1200 (на машине разработки, поскольку я думаю, что это глобальный), чтобы увидеть блокировки, снятые для себя
SET NOCOUNT ON;
CREATE TABLE ##T
(
X INT
)
INSERT INTO ##T
SELECT number
FROM master..spt_values
CREATE TABLE #T
(
X INT
)
INSERT INTO #T
SELECT *
FROM ##T
/*Run the commands first with the trace flag off so the locking
info is less full of irrelevant stuff about plan compilation
*/
GO
PRINT '##T Read Committed'
SELECT COUNT(*) FROM ##T
PRINT '##T NOLOCK'
SELECT COUNT(*) FROM ##T WITH (NOLOCK)
PRINT '##T Finished'
GO
PRINT '#T Read Committed'
SELECT COUNT(*) FROM #T
PRINT '#T NOLOCK'
SELECT COUNT(*) FROM #T WITH (NOLOCK)
PRINT '#T Finished'
GO
DBCC TRACEON(-1,3604)
DBCC TRACEON(-1,1200)
GO
PRINT '##T Read Committed'
SELECT COUNT(*) FROM ##T
PRINT '##T NOLOCK'
SELECT COUNT(*) FROM ##T WITH (NOLOCK)
PRINT '##T Finished'
GO
PRINT '#T Read Committed'
SELECT COUNT(*) FROM #T
PRINT '#T NOLOCK'
SELECT COUNT(*) FROM #T WITH (NOLOCK)
PRINT '#T Finished'
GO
DBCC TRACEOFF(-1,3604)
DBCC TRACEOFF(-1,1200)
DROP TABLE ##T
DROP TABLE #T
для глобальной таблицы temp это неудивительно делает больше разницы.
есть еще небольшая разница в типе блокировки для local #temp
таблицы, хотя. Я воспроизвожу эту часть вывода ниже
#T Read Committed
Process 56 acquiring IS lock on OBJECT: 2:301244128:0 (class bit0 ref1) result: OK
Process 56 acquiring S lock on OBJECT: 2:301244128:0 (class bit0 ref1) result: OK
Process 56 releasing lock on OBJECT: 2:301244128:0
#T NOLOCK
Process 56 acquiring Sch-S lock on OBJECT: 2:301244128:0 (class bit0 ref1) result: OK
Process 56 acquiring S lock on HOBT: 2:9079256880114171904 [BULK_OPERATION] (class bit0 ref1) result: OK
Process 56 releasing lock on OBJECT: 2:301244128:0
Edit: вышеуказанные результаты для кучи. Для временных таблиц с кластерным индексом результаты приведены ниже.
#T Read Committed
Process 55 acquiring IS lock on OBJECT: 2:1790629422:0 (class bit0 ref1) result: OK
Process 55 acquiring S lock on OBJECT: 2:1790629422:0 (class bit0 ref1) result: OK
Process 55 releasing lock on OBJECT: 2:1790629422:0
#T NOLOCK
Process 55 acquiring Sch-S lock on OBJECT: 2:1790629422:0 (class bit0 ref1) result: OK
Process 55 releasing lock on OBJECT: 2:1790629422:0
#T Finished
причина BULK_OPERATION
блокировка на версии кучи пояснил, что. Но видно,что накладные расходы на блокировку довольно минимальны.
вряд ли это имеет большое значение, так как область временных таблиц-одно и то же соединение.
вы конкурируете только за замки с самим собой в той же связи, и если Вы читаете временную таблицу, то вы, вероятно, единственный, кто делает это.
в целом, его, вероятно, лучше не чрезмерно оптимизировать и доверять SQL Server query engine, чтобы хорошо выполнять свою работу. Подождите, пока у вас есть проблема, прежде чем пытаться исправить что угодно.
EDIT (немного не по теме): (обновлена ссылка)
однако существует некоторое обсуждение влияния на всю tempdb при создании временной таблицы. Возможно, удастся оптимизировать - посмотреть здесь (однако это старая статья-SQL Server 6.5 / 7.0), и его вероятный SQL Server 2000 вверх имеет дело с этим сценарием автоматически
опять же, я рекомендую подождать, пока у вас не возникнет проблема усложняю твое решение.
Это может иметь огромное значение в зависимости от вашего запроса. Я сократил время выполнения запроса с 1295 до 590, просто добавив (без блокировки) в свою временную таблицу. Результаты могут отличаться.