Take the 2-minute tour ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

As a follow-up to my previous question on perf troubleshooting a Sharepoint site, I was wondering if I could do something about the CXPACKET waits.

I know the knee-jerk solution is to turn off all parallelism by setting MAXDOP to 1 - sounds like a bad idea. But another idea is to increase the cost threshold before parallelism kicks in. The default of 5 for the cost of an execution plan is fairly low.

So I was wondering if there's a query out there already written that would find me the queries with the highest execution plan cost (I know you can find those with the highest duration of execution and so on - but is the execution plan cost retrievable somewhere, too?) and that would also tell me if such a query has been executed in parallel.

Does anyone have such a script at hand, or can point me in the direction of the relevant DMV, DMF or other system catalog views to find this out?

share|improve this question
    
I'm sure you can do this for RECENT queries by parsing the xml in the plan cache... –  JNK Jul 23 '12 at 18:42
    
@JNK: so that would be stored in dm_exec_cached_plans? There's a lot of DMV's and DMF's in that regard - but I still haven't found any of them showing the cost of the execution plan ... –  marc_s Jul 23 '12 at 18:44
    
I'm checking it out now, give me a few. –  JNK Jul 23 '12 at 18:45
6  
CXPACKET waits are not a problem per se. The issue is typically an uneven distribution of work across threads such that one is still working away after the others are done. If you can identify the thread that's still working, it may have a waittype of interest that you can do something about. Also take a look at the estimated vs actuals row counts for these queries as that can be the cause of poor distribution of rows across threads. –  Mark Storey-Smith Jul 23 '12 at 18:45
    
I'm looking in sys.dm_exec_query_plan –  JNK Jul 23 '12 at 18:45

3 Answers 3

up vote 6 down vote accepted

CXPACKET is never a cause; it gets all the blame, but it's always a symptom of something else. You need to catch these queries in the act and figure out what "something else" is. It might be different from query to query, and turning off parallelism altogether is - as you've suggested - unnecessary overkill in most cases. But it is often the least amount of work, which is why it is such a prevalent "fix."

If you can get an actual plan for a query that seems to be responsible for high CXPACKET waits, load it into SQL Sentry Plan Explorer. There's usually a reason behind this; we show which parallel operations led to thread skew, and you can easily correlate that to estimates that are off (we highlight operations with estimates that are off by a at least certain threshold). Usually the underlying problem is really bad/out-of-date (or unavailable) statistics.

Unfortunately what you'll find in sys.dm_exec_cached_plans are estimated plans. They won't tell you whether the plan went parallel when it was actually used, because the actual plan is not what's cached. In some cases you expect to see both a serial and parallel plan for the same query; this is not how SQL Server deals with the situation for parallel plans that might be parallel at runtime. (Lots of information about that here.)

share|improve this answer
    
Thanks for your insightful response, Aaron! I'll try and see if I can get an actual execution plan of a horrible query - and see if the excellent SQL Sentry Plan Explorer can help me identify the issue(s) - thanks again! –  marc_s Jul 24 '12 at 8:58

The above answer by Aaron is correct.

I'd just like to add that, if you're not already using SQL Performance Dashboard Reports and the built-in Data Collector, you should start.

You could also take the following query, and modify it as you see fit:

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
share|improve this answer

If you wish to see the actual execution plan of a query that is running.

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

First then enter the result into this query.

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

That will show you actual execution plan that sql used for that query. You could use that execution plan to see which thread you are waiting on.

I have also found that turning off hyper threading drastically reduced my CXpacket wait times.

Hope that helps.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.