Xử lý chờ đợi CXPACKET - đặt ngưỡng chi phí cho song song


12

Theo câu hỏi trước đây của tôi về cách khắc phục sự cố hoàn hảo một trang web Sharepoint , tôi đã tự hỏi liệu tôi có thể làm gì đó về việc chờ đợi CXPACKET không.

Tôi biết giải pháp giật đầu gối là tắt tất cả các chế độ song song bằng cách đặt MAXDOP thành 1 - nghe có vẻ là một ý tưởng tồi. Nhưng một ý tưởng khác là tăng ngưỡng chi phí trước khi song song bắt đầu. Mặc định 5 cho chi phí của một kế hoạch thực hiện là khá thấp.

Vì vậy, tôi đã tự hỏi nếu có một truy vấn ngoài đó đã được viết sẽ tìm cho tôi các truy vấn có chi phí kế hoạch thực hiện cao nhất (tôi biết bạn có thể tìm thấy những truy vấn có thời gian thực hiện cao nhất, v.v. - nhưng chi phí kế hoạch thực hiện có thể truy xuất được ở đâu đó, quá?) và điều đó cũng sẽ cho tôi biết nếu một truy vấn như vậy đã được thực hiện song song.

Có ai có sẵn một kịch bản như vậy không, hoặc có thể chỉ cho tôi hướng của DMV, DMF hoặc các khung nhìn danh mục hệ thống khác để tìm ra điều này?

Câu trả lời:


11

CXPACKETkhông bao giờ là một nguyên nhân; tất cả đều bị đổ lỗi, nhưng nó luôn là triệu chứng của một thứ khác. Bạn cần nắm bắt các truy vấn này trong hành động và tìm ra "cái gì khác" là gì. Nó có thể khác với truy vấn đến truy vấn và tắt hoàn toàn song song là - như bạn đã đề xuất - quá mức cần thiết trong hầu hết các trường hợp. Nhưng nó thường là số lượng công việc ít nhất, đó là lý do tại sao nó là một "sửa chữa" phổ biến như vậy.

Nếu bạn có thể nhận được một kế hoạch thực tế cho một truy vấn dường như chịu trách nhiệm cho sự chờ đợi CXPACKET cao, hãy tải nó vào SQL Sentry Plan Explorer . Thường có một lý do đằng sau điều này; chúng tôi chỉ ra các hoạt động song song nào dẫn đến xiên luồng và bạn có thể dễ dàng tương quan điều đó với các ước tính bị tắt (chúng tôi nhấn mạnh các hoạt động với các ước tính bị tắt theo ít nhất một ngưỡng nhất định). Thông thường, vấn đề cơ bản là số liệu thống kê thực sự xấu / lỗi thời (hoặc không có sẵn).

Thật không may, những gì bạn sẽ tìm thấy trong sys.dm_exec_cached_plans là các kế hoạch ước tính . Họ sẽ không cho bạn biết liệu kế hoạch có đi song song khi nó thực sự được sử dụng hay không, bởi vì kế hoạch thực tế không phải là những gì được lưu trong bộ nhớ cache. Trong một số trường hợp, bạn sẽ thấy cả kế hoạch nối tiếp và song song cho cùng một truy vấn; đây không phải là cách SQL Server xử lý tình huống cho các kế hoạch song song thể song song trong thời gian chạy. ( Rất nhiều thông tin về điều đó ở đây .)


4

Nếu bạn muốn xem kế hoạch thực hiện thực tế của một truy vấn đang chạy.

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

Đầu tiên sau đó nhập kết quả vào truy vấn này.

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

Điều đó sẽ cho bạn thấy kế hoạch thực hiện thực tế mà sql đã sử dụng cho truy vấn đó. Bạn có thể sử dụng kế hoạch thực hiện đó để xem chủ đề nào bạn đang chờ đợi.

Tôi cũng đã thấy rằng việc tắt siêu phân luồng làm giảm đáng kể thời gian chờ đợi CXpacket của tôi.

Mong rằng sẽ giúp.


3

Câu trả lời trên của Aaron là chính xác.

Tôi chỉ muốn thêm rằng, nếu bạn chưa sử dụng Báo cáo bảng điều khiển hiệu suất SQLTrình thu thập dữ liệu tích hợp , bạn nên bắt đầu.

Bạn cũng có thể thực hiện truy vấn sau và sửa đổi nó khi bạn thấy phù hợp:

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

Theo kinh nghiệm trước đây của tôi Ngưỡng chi phí cho tính song song không giúp giảm CXPACKET.

CXPACKETChờ đợi cao có thể xảy ra do số liệu thống kê không chính xác dẫn đến Sallwed Parallellism.

  1. Thông tin thêm về CXPACKET Chờ đợi: Skewed Parallelism
  2. Mục kết nối Microsoft
  3. Truy vấn của tôi là (Không) Chờ đợi vì Song song? - Tim Ford

Sau đây là SQL tôi đã sử dụng để tìm các phiên có cả CXPacket và " chờ đợi khác " trong đó (vui lòng xem dagram bên dưới).

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]

nhập mô tả hình ảnh ở đây

Quét lớn cũng có thể là một phần của nguyên nhân gốc rễ. Khi tôi kiểm tra kế hoạch thực hiện từ truy vấn trên, tôi đã tìm thấy một lần quét như vậy trong cơ sở dữ liệu của mình. Ngoài ra còn có một gợi ý chỉ mục bị thiếu trong kế hoạch thực hiện.

nhập mô tả hình ảnh ở đây


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.