Робота з CXPACKET чекає - встановлення порогу вартості для паралелізму


12

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

Я знаю, що рішенням колінного ривка є вимкнути весь паралелізм, встановивши MAXDOP на 1 - це звучить як погана ідея. Але інша ідея полягає в тому, щоб збільшити поріг витрат до початку паралелізму. За замовчуванням 5 для плану виконання програми досить 5.

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

Хтось має такий сценарій під рукою, або може вказати мені у напрямку відповідних DMV, DMF чи інших переглядів системного каталогу, щоб дізнатися це?

Відповіді:


11

CXPACKETніколи не є причиною; вона отримує всю провину, але це завжди симптом чогось іншого. Потрібно зафіксувати ці запити в акті і з’ясувати, що таке «щось інше». Це може відрізнятися від запиту до запиту, а відключення паралелізму взагалі - як ви запропонували - непотрібне перевищення в більшості випадків. Але це найчастіше найменший обсяг роботи, саме тому це таке поширене «виправлення».

Якщо ви можете отримати реальний план для запиту, який, здається, відповідає за високі очікування CXPACKET, завантажте його в SQL Sentry Plan Explorer . Зазвичай у цьому є причина; ми показуємо, які паралельні операції призвели до перекосу потоку, і ви можете легко співвіднести це з відключеними оцінками (ми виділяємо операції з оцінками, які відхилені хоча б певним порогом). Зазвичай основна проблема - це дійсно погана / застаріла (або недоступна) статистика.

На жаль, те, що ви знайдете в sys.dm_exec_cached_plans, - це орієнтовні плани. Вони не скажуть вам, чи йшов план паралельно, коли він фактично використовувався, оскільки фактичний план - це не те, що кешується. У деяких випадках ви очікуєте побачити як послідовний, так і паралельний план для одного запиту; Це не так, як SQL Server вирішує ситуацію для паралельних планів, які можуть бути паралельними під час виконання. (Тут багато інформації про це .)


4

Якщо ви хочете побачити реальний план виконання запиту, який виконується.

SELECT plan_handle FROM sys.dm_exec_requests WHERE session_id = [YourSPID]

Спочатку введіть результат у цей запит.

SELECT query_plan FROM sys.dm_exec_query_plan (Enter the result here.)

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

Я також виявив, що вимкнення гіперпотоку різко скоротило час очікування CXpacket.

Сподіваюся, що це допомагає.


3

Наведена вище відповідь Аарона правильна.

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

Ви також можете взяти такий запит і змінити його, як вважаєте за потрібне:

DECLARE @MinExecutions int; 
SET @MinExecutions = 5 

SELECT EQS.total_worker_time AS TotalWorkerTime 
      ,EQS.total_logical_reads + EQS.total_logical_writes AS TotalLogicalIO 
      ,EQS.execution_count As ExeCnt 
      ,EQS.last_execution_time AS LastUsage 
      ,EQS.total_worker_time / EQS.execution_count as AvgCPUTimeMiS 
      ,(EQS.total_logical_reads + EQS.total_logical_writes) / EQS.execution_count  
       AS AvgLogicalIO 
      ,DB.name AS DatabaseName 
      ,SUBSTRING(EST.text 
                ,1 + EQS.statement_start_offset / 2 
                ,(CASE WHEN EQS.statement_end_offset = -1  
                       THEN LEN(convert(nvarchar(max), EST.text)) * 2  
                       ELSE EQS.statement_end_offset END  
                 - EQS.statement_start_offset) / 2 
                ) AS SqlStatement 
      -- Optional with Query plan; remove comment to show, but then the query takes !!much longer!! 
      --,EQP.[query_plan] AS [QueryPlan] 
FROM sys.dm_exec_query_stats AS EQS 
     CROSS APPLY sys.dm_exec_sql_text(EQS.sql_handle) AS EST 
     CROSS APPLY sys.dm_exec_query_plan(EQS.plan_handle) AS EQP 
     LEFT JOIN sys.databases AS DB 
         ON EST.dbid = DB.database_id      
WHERE EQS.execution_count > @MinExecutions 
      AND EQS.last_execution_time > DATEDIFF(MONTH, -1, GETDATE()) 
ORDER BY AvgLogicalIo DESC 
        ,AvgCPUTimeMiS DESC

0

З мого попереднього досвіду Порогова вартість для паралелізму не допомогла зменшити CXPACKET.

Високе CXPACKETочікування може статися через неправильну статистику, що призводить до скасованого паралелізму.

  1. Детальніше про CXPACKET Waits: Skewed Parallelism
  2. Елемент Microsoft Connect
  3. Мій запит (не) чекає через паралелізм? - Тім Форд

Далі йде SQL, за допомогою якого я знаходив сеанси, в яких є і CXPacket, і " інші очікування " (див. Даграму нижче).

SQL

DECLARE @RawResult TABLE ([database_id] INT,[session_id] INT,exec_context_id INT, [blocking_session_id] INT,task_state VARCHAR(20),
                          [cpu_time] BIGINT,[wait_duration_ms] BIGINT, [wait_type] VARCHAR(100),[resource_description] nvarchar(3072),
                          [sql_handle] varbinary(64),[plan_handle] varbinary(64)
                          )
INSERT INTO @RawResult
SELECT 
    [R].[database_id],
    [S].[session_id],
    [W].exec_context_id,
    [W].blocking_session_id,
    [T].task_state,
    [R].[cpu_time],
    [W].[wait_duration_ms],
    [W].[wait_type],
    [W].[resource_description],
    [R].[sql_handle],
    [R].[plan_handle]
FROM sys.dm_os_waiting_tasks [W]
INNER JOIN sys.dm_os_tasks [T] ON
    [W].[waiting_task_address] = [T].[task_address]
INNER JOIN sys.dm_exec_sessions [S] ON
    [W].[session_id] = [S].[session_id]
INNER JOIN sys.dm_exec_requests [R] ON
    [S].[session_id] = [R].[session_id]
WHERE [S].[is_user_process] = 1
--AND S.session_id <> @@SPID--???
--ORDER BY [W].[session_id],[W].[exec_context_id];


SELECT  
    DB_NAME(C.database_id) AS database_name,
    C.[database_id],
    C.[session_id],
    C.exec_context_id,
    C.blocking_session_id,
    C.task_state,
    C.[cpu_time],
    C.[wait_duration_ms],
    C.[wait_type],
    C.[sql_handle],
    C.[plan_handle],
    [H].text,
    [P].[query_plan],
    C.[resource_description]
FROM @RawResult C
OUTER APPLY sys.dm_exec_sql_text (C.[sql_handle]) [H]
OUTER APPLY sys.dm_exec_query_plan (C.[plan_handle]) [P]
WHERE C.[session_id] IN
                    (
                        SELECT A.[session_id]
                        FROM @RawResult A
                        INNER JOIN @RawResult B
                            ON A.[session_id] = B.[session_id]
                            AND A.wait_type='CXPACKET'
                            AND B.wait_type <> 'CXPACKET'
                    )
ORDER BY C.[session_id],C.[exec_context_id]

введіть тут опис зображення

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

введіть тут опис зображення


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