Чи НОЛОК завжди поганий?


34

Я розробник звітів, який хоче зробити мої запити максимально ефективними. Раніше я працював з DBA, який сказав мені - я вважаю, тому що я завжди мав справу зі звітами на виробничому сервері - для використання NOLOCKу кожному запиті.

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

Оскільки в більшості моїх навчань SQL присутні різні DBA з дуже різними думками, я хотів запитати це для широкого спектру DBA.


1
Інша сторона цього обговорення: dba.stackexchange.com/q/2684/2660
Нік Чаммас

Відповіді:


30

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

На мою думку, завжди є кращі альтернативи, ніж NOLOCK:

  • Чи читаються ваші виробничі таблиці лише на ділі і ніколи не змінюються? Позначте базу даних лише для читання!
  • Сканування таблиці викликає конфлікти блокування? Індексуйте таблиці відповідним чином, переваги множинні.
  • Не можете змінити / не знаєте, як правильно індексувати? Використовуйте ІЗОЛЯЦІЮ SNAPSHOT .
  • Не вдається змінити додаток для використання знімка? Увімкніть читання зроблених знімків !
  • Ви виміряли вплив версій версій і маєте докази, що це впливає на ефективність? Ви не можете індексувати дані? і вам все в порядку з неправильними повідомленнями ? Тоді як мінімум зробіть собі прихильність і використовуйте SET TRANSACTION ISOLATION LEVEL, а не натяк на запит. Пізніше буде простіше виправити рівень ізоляції, а не змінювати кожен запит.

6
Будьте уважні: увімкнення читання зробленого знімка може порушити деякий код.
АК

33

Це не завжди погано.

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

Єдині рівні ізоляції, які гарантують, що ви не зіткнетеся з подібними аномаліями, - це серіалізація / знімок. Під повторюваними значеннями зчитування можна пропустити, якщо рядок переміщено (за рахунок оновлення ключа) до того, як сканування досягне цього рядка, під знаками, здійсненими для читання, можна прочитати двічі, якщо оновлення ключа змушує попередньо прочитану рядок рухатися вперед.

Ці питання, швидше за все, виникають у зв'язку з nolockтим, що, за замовчуванням, на цьому рівні ізоляції він використовуватиме впорядкований розподіл сканування, коли, за оцінками, потрібно прочитати понад 64 сторінки . Як і категорія питань, що виникають при переміщенні рядків між сторінками через оновлення ключових індексів, ці впорядковані сканування розподілу також вразливі до проблем із розщепленнями сторінок (де рядки можна пропустити, якщо новопризначена сторінка знаходиться раніше у файлі, ніж точка вже відскановано або прочитано двічі, якщо вже відскановану сторінку розділити на пізнішу сторінку у файлі).

Принаймні, для простих запитів (за однією таблицею) можна відмовитися від використання цих сканувань і отримати сканований ключ за nolockдопомогою простого додавання ORDER BY index_keyдо запиту, щоб Orderedвластивість IndexScanбула true.

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

Але, безумовно, не варто це робити за всіма запитами, сподіваючись, що це чарівна кнопка "турбо". Окрім більшої ймовірності зустріти аномальні результати на тому рівні ізоляції або взагалі відсутні результати ("Не вдалося продовжити сканування за допомогою NOLOCK через помилку руху даних"), є навіть випадки, коли продуктивність nolock може бути набагато гіршою .


3
+1 - Ми його багато використовуємо, оскільки наші виробничі таблиці ніколи не змінюються.
JNK

@JNK Що ти маєш на увазі під тим, що ніколи не змінюється?
Kuberchaun

4
Мартіне, я б запропонував трохи інші слова: "при прочитаних допущених значеннях можна як пропустити, так і прочитати не раз". У деяких екзотичних випадках ряд може бути отриманий більше ніж два рази.
АК

@ StarShip3000 Дані, які ми розміщуємо у виробництві, в основному доступні лише для читання кінцевим користувачам, тому більшість їхніх поглядів мають підказки NOLOCK
JNK

11

Чи допускають ваші клієнти непослідовні результати у звітах? Якщо відповідь «ні», не слід використовувати NOLOCK - за одночасності можна отримати неправильні результати. Я написав кілька прикладів тут , тут і тут . Ці приклади показують суперечливий вихід під READ COMMITTED та REPEATABLE READ, але ви можете налаштувати їх та отримати неправильні результати також за допомогою NOLOCK.


Більшість створених мною звітів не працює за поточними даними. Більшість клієнтів ведуть звіти - це вчорашні дані. Чи змінилася б ваша відповідь, якби це було так?
DataGirl

8

Більшість створених мною звітів не працює за поточними даними. Більшість клієнтів мають звіти - це вчорашні дані. Чи змінилася б ваша відповідь, якби це було так?

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

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

Я власний розробник, тому мені це простіше, тому що маю повний контроль над серверами та базами даних.

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

У мене така ж ситуація і на роботі:
ми використовуємо подібну копію виробничої бази даних для майже всіх матеріалів звітності, але є кілька запитів, які потребують сьогоднішніх даних.


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