Як запобігти тупикам із розділеними стовпцями на SELECT


10

У мене є три таблиці індексу кластерних стовпців (CCI) в SQL Server 2016. Усі ці ІСЦ є в одній схемі розподілу на основі ідентифікатора орендатора. Останнім часом, і непослідовно, я отримую тупики на простих операторах вибору від приєднання до цих таблиць. Приклад запиту про тупикові місця:

SELECT  TOP 33 r.tenantid
FROM    Table_r r
        INNER JOIN Table_cm cm ON r.MyKey=cm.MyKey 
        INNER JOIN Table_pe pe ON r.MyKey=pe.MyKey 
WHERE   r.TenantId = 69
        AND pe.TenantId = 69
        AND cm.TenantId = 69

Повідомлення про помилку:

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

Підказки:

  • Якщо запит використовує інший індекс, крім CCI, він не зупиняється.
  • Якщо я вийму два з трьох тенантідних фільтрів, він не зупиниться.
  • Якщо Я ВИБІРУТУ верхню 32 або нижню, вона не заходить у тупик.
  • Якщо я додам OPTION (MAXDOP 1), він не заходить у тупик.
  • Я можу спростувати це у своїй зашифрованій репліці PROD, PROD READ-ONLY Secondary і самому PROD.
  • Я не можу спростувати цю поведінку в DEV або INT.
  • Він все ще залишається в глухих куточках, якщо я додати З (NOLOCK) до всіх 3 приєднань таблиці
  • Самі тупикові запити. Він зайде в тупик, коли немає інших активних процесів.
  • Плани запитів без паралелізму не заходять у тупик

Тупик xml тут

Наша версія PROD:

Microsoft SQL Server 2016 (SP2-CU5) (KB4475776) - 13.0.5264.1 (X64) 10 січня 2019 18:51:38 Авторські права (c) Microsoft Corporation Enterprise Edition (64-розрядна) на Windows Server 2012 R2 Standard 6.3 (збірка 9600 :) (Гіпервізор)

Як запобігти тупиковість у цьому запиті?

Відповіді:


8

Оскільки ви перебуваєте на SQL Server 2016, варто згадати, що існує принаймні одне виправлення помилок для паралельних тупиків із залученням індексів стовпців:

Виправлення: тупик виникає під час запуску паралельного запиту на кластерному індексі стовпців у SQL Server 2016 та 2017

(спасибі Денису Рубашкіну за надання посилання спочатку)

Це було випущено у складі SP1 CU7. Якщо вам не підходить до цього МС, вам слід це зробити. Це виправлення також буде включене в SP2 (будь-який із МС).

Загалом, два підходи для фіксації тупік-паралелізму внутрішньозапиту:

  • уникати паралелізму (шляхом настройки запиту так , що він не йде паралельно, використовуючи MAXDOPпідказку і т.д.) - це розглядається в іншому відповіді по Томас Costers
  • застосувати останні оновлення пакета обслуговування / накопичувальні оновлення до SQL Server

2

Ви перевірили наступний блог у тупіках паралельної тематики внутрішніх запитів

SyncPointРесурс вказує на використання обмінної випадку , якщо я не помиляюся.
Дивлячись на учасників вашої тупикової точки, ви можете побачити, що всі вони походять з одного і того ж павука (55) та партії (0), але використовують різні нитки. Це вказує на те, що всі вони є частиною одного і того ж паралельного запиту і підтверджується тим, що ви не отримуєте жодних тупикових ситуацій під час запуску запиту MAXDOP 1. У випадку тупиків внутрішніх запитів паралельних потоків нитки одного запиту закінчуються тупиковим блокуванням один одного в очікуванні об’єктів синхронізації, SyncPoints у вашому випадку.

Востаннє, коли я був свідком подібної поведінки, мені вдалося додатково оптимізувати запит і тим самим запобігти запиту використовувати паралельний план виконання. Я підозрюю, що ви зробили те саме, обмеживши набір результатів на 32 записи або використовуючи інший індекс.
Іншим варіантом було б додати MAXDOP 1до вашого запиту, хоча він не є великим шанувальником цього варіанту.

Але перед тим, як познайомитись із цими двома варіантами, спочатку перевірте, чи є у вас останній SP / CU.

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