SQL Server to troubleshoot high CPU utilization.

A friend asked me to help him look at the database, the operating system is Windows 2008 R2, the database is SQL 2008 R2 64 bits. Hardware configuration is still relatively high, 64G memory, 16-core CPU, he said that the server is running Kingdee K3 software, database instances there are multiple databases.

phenomenon

He said that these days only appeared, but also will be high CPU utilization occurs at a certain time each day

Memory usage is not too high, only takes 30 G

100% CPU utilization

 

 

The direction of the investigation

General investigation are with the following script, usually used three views sys.sysprocesses, dm_exec_sessions, dm_exec_requests

1

2

3

4

5

USE master

GO

- If you want to specify the database took remove comments

SELECT * FROM sys.[sysprocesses] WHERE [spid]>50 --AND DB_NAME([dbid])="gposdb"

SELECT COUNT(*) FROM [sys].[dm_exec_sessions] WHERE [session_id]>50

Look at the current database user connections number

Then use the following statement to look at the indicators are normal, whether there is obstruction, this statement is selected sessions of the top 10 most CPU time consuming

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

SELECT TOP 10

[session_id],

[request_id],

[Start_time] AS "start time"

[Status] AS "Status",

[command] AS "命令",

dest.[text] AS "sql语句",

DB_NAME ([database_id]) AS "database name"

[Blocking_session_id] AS "session ID blocking other sessions"

[Wait_type] AS "waiting for resource type"

[Wait_time] AS "waiting time"

[Wait_resource] AS "resource waiting"

[Reads] AS "number of physical reads"

[Writes] AS "write the number"

[Logical_reads] AS "number of logical reads"

[Row_count] AS "Returns the number of rows in the result"

FROM sys.[dm_exec_requests] AS der

CROSS APPLY

sys.[dm_exec_sql_text](der.[sql_handle]) AS dest

WHERE [session_id]>50 AND DB_NAME(der.[database_id])="gposdb"

ORDER BY [cpu_time] DESC

If you want to see a specific SQL statement can execute the following SQL statement, remember to choose to display the results in text format in SSMS

1

2

3

4

5

6

7

- Select SSMS results in display in text format

SELECT TOP 10

dest.[text] AS "sql语句"

FROM sys.[dm_exec_requests] AS der

CROSS APPLY

sys.[dm_exec_sql_text](der.[sql_handle]) AS dest  WHERE [session_id]>50

ORDER BY [cpu_time] DESC

Mimics some of the operation of CPU time consumption

 

 

There are several viewing CPU scheduler, and user number and the maximum number of worker threads, to check whether the worker can also run out of CPU utilization investigation

1

2

3

4

- Check the number of CPU scheduler, and user number

SELECT cpu_count,scheduler_count FROM sys.dm_os_sys_info

- The maximum number of worker threads View

SELECT max_workers_count FROM sys.dm_os_sys_info

View all schedulers on the machine, including user and system

The following statement can be seen whether the worker runs out, when the maximum number of threads necessary to check the blocking

The following comparison table

The maximum number of worker threads various combinations of CPU and SQLSERVER version autoconfiguration

Number of 32-bit computer CPU 64 computer

<=4         256                    512

8            288                    576

16           352                    704

32           480                    960

1

2

3

4

5

6

7

8

SELECT

scheduler_address,

scheduler_id,

cpu_id,

status,

current_tasks_count,

current_workers_count,active_workers_count

FROM sys.dm_os_schedulers

If there is a resource SQLSERVER to wait, then execute the following statement will show how many sessions worker waiting

Combined with [sys]. [Dm_os_wait_stats] view, if the current SQLSERVER there is no waiting for a resource, then the following SQL statement does not show any results

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

SELECT TOP 10

[session_id],

[request_id],

[Start_time] AS "start time"

[Status] AS "Status",

[command] AS "命令",

dest.[text] AS "sql语句",

DB_NAME ([database_id]) AS "database name"

[Blocking_session_id] AS "session ID blocking other sessions"

der. [wait_type] AS "waiting for resource type"

[Wait_time] AS "waiting time"

[Wait_resource] AS "resource waiting"

[Dows]. [Waiting_tasks_count] AS "number of tasks currently in progress waiting"

[Reads] AS "number of physical reads"

[Writes] AS "write the number"

[Logical_reads] AS "number of logical reads"

[Row_count] AS "Returns the number of rows in the result"

FROM sys.[dm_exec_requests] AS der

INNER JOIN [sys].[dm_os_wait_stats] AS dows

ON der.[wait_type]=[dows].[wait_type]

CROSS APPLY

sys.[dm_exec_sql_text](der.[sql_handle]) AS dest

WHERE [session_id]>50

ORDER BY [cpu_time] DESC

For example, I currently executing the query SalesOrderDetail_test table 100, due to the very large table of data, so the results need to SSMS SQLSERVER performed slowly removed,

Caused ASYNC_NETWORK_IO wait

1

2

3

4

USE [AdventureWorks]

GO

SELECT * FROM dbo.[SalesOrderDetail_test]

GO 100

Source of the problem

Through observation and investigation of the case these days, is to determine the cause of some tables are missing indexes, now adds indexes on these tables, problem solving

1

2

3

4

5

6

select * from t_AccessControl - access control list access control

select * from t_GroupAccess - user group permissions user group permissions table

select * from t_GroupAccessType - user group permissions user group permissions class class table

select * from t_ObjectAccess - object privileges table object privileges

select * from t_ObjectAccessType - the type of object permissions table object permission type

select * from t_ObjectType - object type object type table

High CPU usage query statement

1

2

3

4

5

6

7

8

9

10

11

SELECT TOP 10

total_worker_time/execution_count AS avg_cpu_cost, plan_handle,

execution_count,

(SELECT SUBSTRING(text, statement_start_offset/2 + 1,

(CASE WHEN statement_end_offset = -1

THEN LEN(CONVERT(nvarchar(max), text)) * 2

ELSE statement_end_offset

END - statement_start_offset)/2)

FROM sys.dm_exec_sql_text(sql_handle)) AS query_text

FROM sys.dm_exec_query_stats

ORDER BY [avg_cpu_cost] DESC

Missing index query

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

SELECT

DatabaseName = DB_NAME(database_id)

,[Number Indexes Missing] = count(*)

FROM sys.dm_db_missing_index_details

GROUP BY DB_NAME(database_id)

ORDER BY 2 DESC;

SELECT TOP 10

[Total Cost] = ROUND(avg_total_user_cost * avg_user_impact * (user_seeks + user_scans),0)

, avg_user_impact

, TableName = statement

, [EqualityUsage] = equality_columns

, [InequalityUsage] = inequality_columns

, [Include Cloumns] = included_columns

FROM sys.dm_db_missing_index_groups g

INNER JOIN sys.dm_db_missing_index_group_stats s

ON s.group_handle = g.index_group_handle

INNER JOIN sys.dm_db_missing_index_details d

ON d.index_handle = g.index_handle

ORDER BY [Total Cost] DESC;

 

 

(View larger image)

After locating the problem, a new non-clustered index

1

2

3

4

5

6

7

CREATE NONCLUSTERED INDEX IX_t_AccessControl_F4 ON dbo.t_AccessControl

(

FObjectType

)include([FUserID], [FAccessType], [FAccessMask]) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

GO

drop index IX_t_AccessControl_F4 on t_AccessControl

CPU usage is back to normal

Tracking template and trace files to download, use SQL2008R2 version: files.cnblogs.com/lyhabc/ tracking templates and trace.rar

to sum up

From historical experience, many times, if sustained high CPU load, memory and IO are okay but then, in this case, the first thought must be the index of the problem, in all likelihood can not go wrong.

Note that at the beginning of the article posted on the client machine load chart

Published 60 original articles · won praise 52 · views 110 000 +

Guess you like

Origin blog.csdn.net/yihuliunian/article/details/104696886