要对当前已经在使用的SQLSERVER系统的硬件资源进行检查。下面的脚本可以运行在当前系统方便找出硬件的信息,用户可以根据具体的硬件信息对数据库进行调优处理。
-- 当前数据库文件的I/O 统计信息
SELECT DB_NAME(DB_ID()) AS [Database Name] ,
[file_id] ,
num_of_reads ,
num_of_writes ,
num_of_bytes_read ,
num_of_bytes_written ,
CAST(100. * num_of_reads / ( num_of_reads + num_of_writes ) AS DECIMAL(10,
1)) AS [# Reads Pct] ,
CAST(100. * num_of_writes / ( num_of_reads + num_of_writes ) AS DECIMAL(10,
1)) AS [# Write Pct] ,
CAST(100. * num_of_bytes_read / ( num_of_bytes_read
+ num_of_bytes_written ) AS DECIMAL(10,
1)) AS [Read Bytes Pct] ,
CAST(100. * num_of_bytes_written / ( num_of_bytes_read
+ num_of_bytes_written ) AS DECIMAL(10,
1)) AS [Written Bytes Pct]
FROM sys.dm_io_virtual_file_stats(DB_ID(), NULL);
除了这个脚本,还有其他3个脚本可用于检查当前系统的读写情况,如代码清单。
–计划缓存中存储过程的逻辑写排名 (SQL 2008 and 2008 R2 适用) ,主要是写操作的压力
--计划缓存中存储过程的逻辑写排名 (SQL 2008 and 2008 R2 适用) ,主要是写操作的压力
SELECT p.name AS [SP Name] ,
qs.total_logical_writes AS [TotalLogicalWrites] ,
qs.total_logical_reads AS [TotalLogicalReads] ,
qs.execution_count ,
qs.cached_time
FROM sys.procedures AS p
INNER JOIN sys.dm_exec_procedure_stats AS qs ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
AND qs.total_logical_writes > 0
ORDER BY qs.total_logical_writes DESC;
计划缓存中存储过程的物理读排名 (SQL 2008 and 2008 R2 适用) ,主要是读操作的压力
--计划缓存中存储过程的物理读排名 (SQL 2008 and 2008 R2 适用) ,主要是读操作的压力
SELECT p.name AS [SP Name] ,
qs.total_physical_reads AS [TotalPhysicalReads] ,
qs.total_logical_reads AS [TotalLogicalReads] ,
qs.total_physical_reads / qs.execution_count AS [AvgPhysicalReads] ,
qs.execution_count ,
qs.cached_time
FROM sys.procedures AS p
INNER JOIN sys.dm_exec_procedure_stats AS qs ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
AND qs.total_physical_reads > 0
ORDER BY qs.total_physical_reads DESC ,
qs.total_logical_reads DESC;
计划缓存中存储过程的逻辑写排名
SELECT p.name AS [SP Name] ,
qs.total_logical_reads AS [TotalLogicalReads] ,
qs.total_logical_writes AS [TotalLogicalWrites] ,
qs.execution_count ,
qs.cached_time
FROM sys.procedures AS p
INNER JOIN sys.dm_exec_procedure_stats AS qs ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
AND qs.total_logical_reads > 0
ORDER BY qs.total_logical_reads DESC;
当一个请求由于某些原因产生等待时,SQL Server会把相关信息存放在sys.dm_os.
wait_stats这个DMV中。很多第三方工具都是通过分析这个DMV中的信息进行问题侦测
的,下面来看个例子。
比如可以用下面语句检查等待类型中等待时间最长的10个类型。
SELECT TOP ( 10 )
wait_type ,
waiting_tasks_count ,
( wait_time_ms - signal_wait_time_ms ) AS resource_wait_time ,
max_wait_time_ms ,
CASE waiting_tasks_count
WHEN 0 THEN 0
ELSE wait_time_ms / waiting_tasks_count
END AS avg_wait_time
FROM sys.dm_os_wait_stats
WHERE wait_type NOT LIKE '%SLEEP%' -- 去除不相关的等待类型
AND wait_type NOT LIKE 'XE%'
AND wait_type NOT IN -- 去除系统类型
( 'KSOURCE_WAKEUP', 'BROKER_TASK_STOP', 'FT_IFTS_SCHEDULER_IDLE_WAIT',
'SQLTRACE_BUFFER_FLUSH', 'CLR_AUTO_EVENT', 'BROKER_EVENTHANDLER',
'BAD_PAGE_PROCESS', 'BROKER_TRANSMITTER', 'CHECKPOINT_QUEUE',
'DBMIRROR_EVENTS_QUEUE', 'SQLTRACE_BUFFER_FLUSH', 'CLR_MANUAL_EVENT',
'ONDEMAND_TASK_QUEUE', 'REQUEST_FOR_DEADLOCK_SEARCH', 'LOGMGR_QUEUE',
'BROKER_RECEIVE_WAITFOR', 'PREEMPTIVE_OS_GETPROCADDRESS',
'PREEMPTIVE_OS_AUTHENTICATIONOPS', 'BROKER_TO_FLUSH' )
ORDER BY wait_time_ms DESC
下面的语句用于查找CPU最高消耗的10个语句,并带有一些相关信息,特别是执行
计划。
SELECT TOP ( 10 )
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 ,
execution_count ,
total_worker_time / 1000 AS total_worker_time_ms ,
( total_worker_time / 1000 ) / execution_count AS avg_worker_time_ms ,
total_logical_reads ,
total_logical_reads / execution_count AS avg_logical_reads ,
total_elapsed_time / 1000 AS total_elapsed_time_ms ,
( total_elapsed_time / 1000 ) / execution_count AS avg_elapsed_time_ms ,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) st
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY total_worker_time DESC
并行操作会把一个查询分开到多个线程中执行,然后再合并到一起返回结果。当-个
查询的开销超过cost threshold for parallelism这个阈值时(默认为5秒),就会检查是否有可
用的CPU用于支持并行操作,其中,并行度取决于max degree of parallelism的值。但是
对于OLTP 系统,并行操作往往是非必需的,过多的并行执行会加重CPU的负担。可以用
下面语句来检查是否存在并行操作的执行计划。
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
WITH XMLNAMESPACES
(DEFAULT 'http://schemas.microsoft.com/SQL Server/2004/07/showplan')
SELECT query_plan AS CompleteQueryPlan ,
n.value('(@StatementText)[1]', 'VARCHAR(4000)') AS StatementText ,
n.value('(@StatementOptmLevel)[1]', 'VARCHAR(25)')
AS StatementOptimizationLevel ,
n.value('(@StatementSubTreeCost)[1]', 'VARCHAR(128)')
AS StatementSubTreeCost ,
n.query('.') AS ParallelSubTreeXML ,
ecp.usecounts ,
ecp.size_in_bytes
FROM sys.dm_exec_cached_plans AS ecp
CROSS APPLY sys.dm_exec_query_plan(plan_handle) AS eqp CROSS APPLY query_plan.nodes
('/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple')
AS qn ( n )
WHERE n.query('.').exist('//RelOp[@PhysicalOp="Parallelism"]') = 1