Ефект підказки NOLOCK у SELECT операторах


199

Я думаю, справжнє питання:

Якщо мене не хвилюють брудні читання, додавання підказки (NOLOCK) до оператора SELECT вплине на продуктивність:

  1. поточний оператор SELECT
  2. інші операції проти даної таблиці

Приклад:

Select * 
from aTable with (NOLOCK)

3
Ці відповіді ТА та БД трохи чіткіші, що насправді відбувається.
Trisped

Відповіді:


289

1) Так , вибір з NOLOCKзавершиться швидше, ніж звичайний.

2) Так , вибір з NOLOCKдозволить іншим запитам проти виконаної таблиці завершуватися швидше, ніж звичайний вибір.

Чому це було б?

NOLOCKзазвичай (залежно від вашого двигуна БД) означає, дайте мені ваші дані, і мені байдуже, у якому стані він знаходиться, і не турбуйтеся, щоб він тримався, поки ви читаєте з нього. Це все відразу швидше, менш ресурсомістке і дуже дуже небезпечно.

Вас слід попередити, щоб ніколи не оновлювали та не виконували нічого критичного для системи або там, де потрібна абсолютна коректність, використовуючи дані, що походять від NOLOCKпрочитаного. Цілком можливо, що ці дані містять рядки, видалені під час запуску запиту або видалені в інших сесіях, які ще не завершені. Можливо, що ці дані включають рядки, які були частково оновлені. Цілком можливо, що ці дані містять записи, що порушують іноземні ключові обмеження. Можливо, що ці дані виключають рядки, які були додані в таблицю, але їх ще не доведено.

Ви справді не можете дізнатися, у якому стані дані.

Якщо ви намагаєтеся отримати такі речі, як кількість рядків або інші зведені дані, де допустима помилка, то NOLOCKце хороший спосіб підвищити ефективність цих запитів і уникнути негативного впливу на роботу бази даних.

Завжди використовуйте NOLOCKпідказку з великою обережністю і ставитесь до будь-яких даних, які вони повертають, підозріло.


Дякую. Це те, про що я припускав, але колега його допитав про це, і мої початкові дослідження змусили мене поставити під сумнів себе. Документація SQLServer 2005 говорить про те, що з NOLOCK є схемою блокування за замовчуванням для всіх вибраних операторів! Тоді я б здогадався, що мої підказки будуть зайвими у ...
Боб Пробст

2
... 2005 р. І не мають жодного ефекту. Зараз ми працюємо 2000 (завдяки нашому постачальнику), і подібної заяви в документації немає.
Боб Пробст

4
Ваш друг повинен прочитати документацію. Підказка на таблицю (Transact-SQL) msdn.microsoft.com/en-us/library/ms187373(SQL.90).aspx
Pittsburgh DBA

9
Побічна примітка: якби це було правдою, це був би абсолютний хаос.
Пітсбург DBA

1
Точки 1 і 2 потрібно обмежити 1) "..., коли дія вставки / оновлення / видалення очікує на таблицю ." та 2) "... дозволить вставити / оновити / видалити запити проти ...". Я хотів би (особисті переваги) змінити випадки "швидше" на "швидше", оскільки різниця чекає завершення іншого процесу.
Trisped

61

NOLOCK робить більшість операторів SELECT швидшими через відсутність спільних блокувань. Крім того, відсутність видачі замків означає, що письменники не будуть перешкоджати вашому SELECT.

НОЛОК функціонально еквівалентний рівню ізоляції ЧИТАЙТЕ НЕЗАКОНЕНО. Основна відмінність полягає в тому, що ви можете використовувати NOLOCK на деяких таблицях, але не на інших, якщо захочете. Якщо ви плануєте використовувати NOLOCK для всіх таблиць у складному запиті, то використовувати SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED простіше, оскільки вам не потрібно застосовувати підказку до кожної таблиці.

Тут представлена ​​інформація про всі наявні у вас рівні ізоляції, а також підказки щодо таблиці.

Встановити рівень ІЗОЛЯЦІЇ ТРАНЗАКЦІЇ

Підказка щодо таблиці (Transact-SQL)


2
Я згоден, але не повністю; важливо зазначити, що підказка NO LOCK / READ UNCOMMITTED насправді не покращує швидкість запиту, але тим більше робить його швидшим, оскільки не потрібно чекати завершення попередніх запитів. Тож справді запит ПОШУЄМО швидше, ніж ІСШ швидше (я думаю).
Möoz

1
@BorhanMooz Ну, це економія від того, що не потрібно запитувати замовлення у менеджера блокування. Навіть якщо немає інших запитів, які чекають, це має витрати та обсяг пам'яті.
Пітсбург DBA

1
Я обговорював це з деякими своїми товаришами по роботі. Як я розумію, запит із використанням підказки WITH (NOLOCK) все ще потребує отримання блокувальної схеми ( mssqltips.com/sqlservertip/2470/… ).
Möoz

1
Так, але не тисячі спільних блокувань на сторінках чи розширеннях. Блокування схеми - це ОДИН замок, а не ТИШИЙ. Якщо ми хочемо бути педантичними, ми можемо продовжувати обговорювати це, але так, буде мінімальна кількість замкових накладних витрат. Економія значна. Робіть математику на цьому: msdn.microsoft.com/en-us/library/aa337559(v=sql.100).aspx
Pittsburgh DBA


6

Це буде швидше, тому що не потрібно чекати замків


На скільки швидше? Не могли б ви надати якісь номери підвищення швидкості?
Eugeniu Torica

5
"Скільки" залежить від того, що ви конкретно робите зі своїми даними та від того, як довго вам доведеться чекати придбання блокування.
StingyJack

Єдиний правильний орієнтир - це той, який ви створюєте та запускаєте самі. Те, що всі вам кажуть, так само добре, як "чек поштою". Я багато разів підтверджував міфи та припущення неправильно, використовуючи власні орієнтири.
TravisO

^ @TravisO - цілком правильно. У мене NOLOCK кілька разів виконувався повільніше. Не зовсім впевнений чому, але я використовую це під час усунення несправностей, і я не хочу негативно (над) впливати на виробництво
StingyJack

2
  • Відповідь - так, якщо запит виконується кілька разів одночасно, тому що для кожної транзакції не потрібно буде чекати, коли інші завершаться. Однак якщо запит виконується один раз самостійно, то відповідь - Ні.

  • Так . Існує велика ймовірність того, що ретельне використання З (NOLOCK) прискорить вашу базу даних в цілому. Це означає, що іншим транзакціям не доведеться чекати завершення цього оператора SELECT, але, з іншого боку, інші транзакції сповільнюватимуться, оскільки тепер вони ділять час обробки з новою транзакцією.

Будьте обережні лише для використанняWITH (NOLOCK) в заявах SELECT , на таблицях , які мають кластерний індекс.

З (NOLOCK) часто використовується як магічний спосіб прискорити транзакції з читання баз даних.

Набір результатів може містити рядки, які ще не були виконані, які часто пізніше повертаються назад.

Якщо З (NOLOCK) застосовується до таблиці з некластеризованим індексом, то індекси рядків можуть бути змінені іншими транзакціями, оскільки дані рядків передаються в таблицю результатів. Це означає, що набір результатів може бути відсутніми рядками або відображати один і той же ряд кілька разів.

ЧИТАЙТЕ ЗАВАНТАЖЕНО додає додаткову проблему, коли дані пошкоджуються в одному стовпчику, де кілька користувачів одночасно змінюють одну клітинку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.