Sql-server – SQL Query in suspended state causing high CPU usage

sql serversql-server-2008

Environment detail: SQL Server 2008 R2. I have applications running on JBoss that access the DB using JDBC driver.

Issue: My online DB server was experiencing high CPU usage.

Using the following query I was able to determine there are 2 queries (Select command) in suspended status (wait type – CXPACKET) for nearly 10 minutes and going on. I believe this is the cause of high CPU usage.

 USE MASTER GO

 SELECT scheduler_id ,
        runnable_tasks_count ,
        pending_disk_io_count
 FROM   sys.dm_os_schedulers
 WHERE  scheduler_id < 255

 SELECT qs.percent_complete ,
        qs.session_id ,
        scheduler_id ,
        blocking_session_id ,
        qs.status ,
        command ,
        wait_time ,
        wait_type ,
        last_wait_type ,
        wait_resource ,
        ST.text ,
        host_name ,
        program_name /*   
 ,SUBSTRING(ST.text, (QS.statement_start_offset/2) + 1,
     (    (CASE statement_end_offset 
           WHEN -1 THEN DATALENGTH(st.text)
           ELSE QS.statement_end_offset END - QS.statement_start_offset  )/2 ) + 1) AS statement_text   */   --, qp.* 
 FROM   sys.dm_exec_requests qs
        LEFT JOIN sys.dm_exec_sessions es ON ( qs.session_id = es.session_id )
        CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS ST
 --     CROSS APPLY sys.dm_exec_query_plan(QS.sql_handle) as qp where qs.session_id = 50 and qs.session_id != @@SPID

 SELECT CASE WHEN Requests.sql_handle IS NULL THEN ' '
             ELSE SUBSTRING(Statements.text,
                            ( Requests.statement_start_offset + 2 ) / 2,
                            ( CASE WHEN Requests.statement_end_offset = -1
                                   THEN LEN(CONVERT(NVARCHAR(MAX), Statements.text))
                                        * 2
                                   ELSE Requests.statement_end_offset
                              END - Requests.statement_start_offset ) / 2)
        END AS StatementText ,
        QueryPlans.query_plan AS QueryPlan ,
        Statements.text AS Batch_Text ,
        Sessions.session_id ,
        Sessions.Login_Name ,
        Sessions.Host_Name ,
        Sessions.Program_Name ,
        Sessions.Client_Interface_Name ,
        Requests.wait_time ,
        Requests.cpu_time ,
        Requests.total_elapsed_time ,
        Requests.reads ,
        Requests.writes ,
        Requests.logical_reads ,
        Requests.row_count ,
        Requests.granted_query_memory * 8 / 1024 AS Granted_Query_Memory_MB ,
        LEN(Statements.text) AS Batch_Text_Length ,
        Requests.statement_start_offset / 2 AS Statement_Start_Offset ,
        CASE WHEN Requests.statement_end_offset = -1
             THEN LEN(CONVERT(NVARCHAR(MAX), Statements.text)) * 2
             ELSE Requests.statement_end_offset
        END / 2 AS Statement_End_Position ,
        ( CASE WHEN Requests.statement_end_offset = -1
               THEN LEN(CONVERT(NVARCHAR(MAX), Statements.text)) * 2
               ELSE Requests.statement_end_offset
          END - Requests.statement_start_offset ) / 2 AS Statement_Text_Length
 FROM   sys.dm_exec_session Sessions
        INNER JOIN sys.dm_exec_requests Requests ON Sessions.session_id = Requests.session_id
        CROSS APPLY sys.dm_exec_sql_text(sql_handle) Statements
        CROSS APPLY sys.dm_exec_query_plan(plan_handle) QueryPlans
 WHERE  Sessions.session_id != @@SPID


 SELECT *
 FROM   sys.dm_exec_requests
 WHERE  blocking_session_id != 0

Any suggestions on how I can kill these queries in suspended state?

Best Answer

Get the session_id returned from your queries above and use the KILL command to kill the queries that are hung. For example if the session_id of the suspended query was 86, then you would run the following.

KILL 86;

IMPORTANT: if any of the queries run batches of insert, update, or delete statements and are not in a transaction so that all changes get rolled back, then you may run into data consistency problems if you kill the query in the middle of processing.