CXPACKET ile başa çıkmak bekliyor - paralellik için maliyet eşiğini ayarlama


12

Bir izlem benim gelince önceki soruya bir Sharepoint sitesi giderme perf üzerine ben CXPACKET beklediği hakkında bir şeyler yapabileceğini, ben merak ediyorum.

Diz-sarsıntı çözümünün MAXDOP'u 1'e ayarlayarak tüm paralellikleri kapatmak olduğunu biliyorum - kulağa kötü bir fikir gibi geliyor. Ancak başka bir fikir, paralellik devreye girmeden önce maliyet eşiğini artırmaktır. Bir yürütme planının maliyeti için varsayılan 5 oldukça düşüktür.

Bu yüzden bana yazılmış en yüksek yürütme planı maliyetine sahip sorguları bulabilecek bir sorgu olup olmadığını merak ediyordum (en yüksek yürütme süresine sahip olanları bulabileceğinizi biliyorum. bu da bana böyle bir sorgunun paralel yürütülüp yürütülmediğini söyler.

Elinizde böyle bir komut dosyası var mı veya bunu bulmak için ilgili DMV, DMF veya diğer sistem kataloğu görünümleri yönünde beni işaret edebilir mi?

Yanıtlar:


11

CXPACKETasla bir sebep değildir; tüm suçu alır, ama her zaman başka bir şeyin belirtisidir. Bu sorguları eylemde yakalamanız ve "başka bir şeyin" ne olduğunu bulmanız gerekir. Sorgudan sorguya farklı olabilir ve paralelliği tamamen kapatmak - önerdiğiniz gibi - çoğu durumda gereksiz yere aşırı kullanmaktır. Ancak çoğu zaman en az çalışma miktarıdır, bu yüzden bu kadar yaygın bir "düzeltme" dir.

Bir alabilirsiniz Eğer gerçek , yüksek CXPACKET bekler sorumlu içine yüklemek gibi görünen bir sorgu için bir plan SQL Sentry Planı Explorer . Bunun arkasında genellikle bir neden vardır; hangi paralel işlemlerin iplik eğriliğine yol açtığını gösteririz ve bunu kapalı tahminlerle kolayca ilişkilendirebilirsiniz (en azından belirli bir eşik ile kapalı tahminlerle işlemleri vurgularız). Genellikle altta yatan sorun gerçekten kötü / güncel olmayan (veya kullanılamıyor) istatistiklerdir.

Maalesef sys.dm_exec_cached_plans içinde bulacağınız şeyler tahmini planlar. Planın gerçekte kullanıldığında paralel olup olmadığını size söylemezler, çünkü gerçek plan önbelleğe alınan şey değildir. Bazı durumlarda, aynı sorgu için hem seri hem de paralel bir plan görmeyi beklersiniz; SQL Server , çalışma zamanında paralel olabilecek paralel planların durumuyla bu şekilde ilgilenmez . (Bu konuda çok fazla bilgi burada .)


4

Çalışan bir sorgunun gerçek yürütme planını görmek istiyorsanız.

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

Önce sonucu bu sorguya girin.

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

Bu size sql bu sorgu için kullanılan gerçek yürütme planı gösterecektir. Beklediğiniz iş parçacığını görmek için bu yürütme planını kullanabilirsiniz.

Ayrıca hiper iş parçacığının kapatılmasının CXpacket bekleme sürelerimi önemli ölçüde azalttığını buldum.

Umarım yardımcı olur.


3

Aaron'ın yukarıdaki cevabı doğrudur.

Sadece şunu eklemek istiyorum, eğer zaten SQL Performans Gösterge Tablosu Raporlarını ve yerleşik Veri Toplayıcı'yı kullanmıyorsanız , başlamalısınız.

Ayrıca, aşağıdaki sorguyu alıp uygun gördüğünüz gibi değiştirebilirsiniz:

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

Daha önceki deneyimlerime göre Paralellik için Maliyet Eşiği CXPACKET'in azaltılmasına yardımcı olmadı.

CXPACKETÇarpık Paralellik ile sonuçlanan yanlış istatistikler nedeniyle yüksek bekleme olabilir.

  1. CXPACKET Waits: Skewed Parallelism hakkında daha fazla bilgi
  2. Microsoft Connect Öğesi
  3. Sorgum Paralellik Nedeniyle Bekliyor? - Tim Ford

Aşağıda, hem CXPacket hem de " diğer beklemeler " içeren oturumları bulmak için kullanılan SQL'dir (lütfen aşağıdaki tabloya bakın).

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]

resim açıklamasını buraya girin

Büyük Taramalar da kök nedeninin bir parçası olabilir. Yukarıdaki sorgudan yürütme planını kontrol ettiğimde, veritabanımda böyle bir tarama buldum. Yürütme planında da eksik bir dizin önerisi vardı.

resim açıklamasını buraya girin


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.