Reference
http://gallery.technet.microsoft.com/ScriptCenter/en-us/
http://technet.microsoft.com/en-us/sqlserver/bb331794.aspx
简介
SQL Server 05提供了动态管理视图Dynamic Management Views和函数 Functions,方便了我们对系统运行情况的监控,故障诊断和性能优化.配合Profiler,dashboard一起使用很不错.
常规服务器动态管理对象包括:
- dm_db_*:数据库和数据库对象
- dm_exec_*:执行用户代码和关联的连接
- --dm_exec_session:类似2k时的sysprocesses 返回:资源,账号等......
- --dm_exec_connections:返回用户认证方式和IP
- --dm_exec_query_stats:
- dm_os_*:内存、锁定和时间安排
- --dm_os_buffer_descriptors
- dm_tran_*:事务和隔离
- --dm_tran_locks: 查看锁定
- dm_io_*:网络和磁盘的输入/输出
我的脚本(DBA 下的存储过程)
- myScript.spBufferUsed 4.2查询某个数据库内个对象使用内存缓存区资源的统计
- myScript.spHighestCPUTime 4.5呈现累积最耗CPU时间的前50个执行计划
- myScript.spListRecompile 4.7 显示累计最常重新编译的25个运行计划
- myScript.spReusedPlans 4.9 重用执行计划
- myScript.spBlockInfo 4.10 显示锁定与被锁定之间的链状关系
- dm_tran_locks没返回一条记录都代表一个已经授予或等待授予的锁定,主要分为:资源"resource"和要求"request"两类前缀
- dm_os_waiting_tasks提供等待时间统计,谁锁定谁的链接信息
- dm_exec_requests和dm_exec_sql_text返回T-SQL
- myScript.spIOInfo 4.13 监控是否有IO延迟的状况 & spIOTopWastedInfo 4.14最耗IO资源的SQL语句
- dm_io_pending_io_requests每有一行返回代表有一项暂停的IO请求
- dm_io_virtual_file_stats动态管理函数可返回数据库文件和记录文件的IO使用统计数据
- myScript.spTempdbUsageStatistics 4.15 统计各连接对 tempdb 系统数据库的占用量
- myScript.spCurrentTempdbUsageStatement 4.16 显示目前连接的语法,及其对 tempdb 系统数据库累计的使用量
常用的SQL Server监控手段总结
- A、查看SQL语句的执行计划,可以在查询分析其使用CTRL+L图形化的显示执行计划,一般应该注意百分比最大的几个图形的属性,把鼠标移动到其上面会显示这个图形的属性,
需要注意预计成本的数据,也要注意其标题,一般都是CLUSTERED INDEX SEEK 、INDEX SEEK 、CLUSTERED INDEX SCAN 、INDEX SCAN 、TABLE SCAN等,其中出现SCAN说明语句有优化的余地。SET SHOWPLAN_ALL ON; SET STATISTICS IO on; SET STATISTICS TIME on; 查看执行计划的文本详细信息。 - B、用事件探查器跟踪系统的运行,可疑跟踪到执行的语句,以及所用的时间,CPU用量以及I/O数据,从而分析语句的效率。
- C、可以用WINDOWS的系统性能检测器,关注CPU、I/O参数
- 使用sys.dm_exec_query_stats和sys.dm_exec_sql_text找到CPU占用率高的语句
各种SQL的执行次数、逻辑IO、物理IO、执行消耗CPU时间等等等等。想想看,假如你拿了一份系统中所有SQL的文本、执行总次数、逻辑IO占用总IO比例、物理IO占用总IO比例、平均逻辑IO、平均物理IO等等等等,你八成能够指出系统瓶颈所在,老板和伙计们的眼光也会会极大的满足你小小的虚荣心,哈。这些东西就在动态视图sys.dm_exec_query_stats里面,自个翻翻联机文档吧:)这里有篇文章不错
SELECT TOP 100 execution_count, total_logical_reads / execution_count AS [ Avg Logical Reads ] , total_elapsed_time / execution_count AS [ Avg Elapsed Time ] , db_name (st.dbid) as [ database name ] , object_name (st.dbid) as [ object name ] , object_name (st.objectid) as [ object name 1 ] , 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 FROM sys.dm_exec_query_stats AS qs CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st WHERE execution_count > 100 and db_name (st.dbid) is not null and db_name (st.dbid) not in ( ' distribution ' ) ORDER BY 1 DESC ; --关于statement_start_offset/2的疑问--注意dm_exec_query_stats仅仅统计与分析在高速缓存中的执行计划,并非所有SQL Server耗时的工作都会有执行计划高速缓存,例如DBCC DBReindex不会被缓存set statistics io on go select top 1 * from sales.customer where customertype <> ' S ' ;CustomerID TerritoryID AccountNumber CustomerType rowguid ModifiedDateCustomerID TerritoryID AccountNumber CustomerType rowguid ModifiedDate ----------- ----------- ------------- ------------ ------------------------------------ ----------------------- 11000 9 AW00011000 I 477586B3-2977-4E54-B1A8-569AB2C7C4D4 2004-10-13 11:15:07.263 (1 行受影响) 表 'Customer'。扫描计数 1,逻辑读取 6 次,物理读取 0 次,预读 0 次,lob 逻辑读取 0 次,lob 物理读取 0 次,lob 预读 0 次。 --如果需要清理缓存池 DBCC DROPCLEANBUFFER
declare @x int ; declare @cpu_start int ; set @x = 1 ; set @cpu_start = @@cpu_busy ; while @x < 10000 set @x = @x + 1 ; print ' ms of cput for loop1: ' + cast ( ( @@cpu_busy - @cpu_start ) + @@timeticks / 1000 as char ); set @cpu_start = @@cpu_busy ; while @x < 100000 set @x = @x + 1 ; print ' ms of cput for loop1: '+ cast ( ( @@cpu_busy - @cpu_start ) + @@timeticks / 1000 as char );--注意这两个参数 @@cpu_busy @@timeticks - 使用sys.dm_exec_cached_plans和sys.dm_exec_sql_text找到执行最频繁的语句 这里有篇文章不错
当dbid值是32767时,就会出现这种情况。因为数据库的ID号与系统数据库,即所谓的资源库是有联系的。这个资源库不是众所周知,但它却是存在于系统中的一个实际数据库,他的确存在,但你在SQL Server Management Studio中却看不到它。在你的数据文件目录下,有一个以字符串“mssqlsystemreource”开始命名的MDF和LDF文件,那就是资源数据库了
SELECT CASE when dbid = 32767 then ' Resource ' else DB_NAME (dbid) end [ DB_NAME ] , OBJECT_SCHEMA_NAME(objectid,dbid) AS [ SCHEMA_NAME ] , OBJECT_NAME (objectid,dbid) AS [ OBJECT_NAME ] , SUM (usecounts) AS [ Use_Count ] , SUM (total_elapsed_time) AS [ total_elapsed_time ] , SUM (total_elapsed_time) / SUM (usecounts) * 1.0 AS [ avg_elapsed_time ] , substring ( convert ( char ( 23 ), DATEADD (ms, sum (total_elapsed_time) / 1000 , 0 ), 121 ), 12 , 23 )AS total_elapsed_time_ms,dbid, objectid FROM sys.dm_exec_cached_plans cp CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) JOIN ( SELECT SUM (total_elapsed_time) AS [ total_elapsed_time ] , plan_handle FROM sys.dm_exec_query_stats GROUP BY plan_handle) qs ON cp.plan_handle = qs.plan_handle WHERE objtype = ' Proc ' AND UPPER ( -- remove white space first REPLACE ( REPLACE ( REPLACE ( REPLACE ( REPLACE ( REPLACE ( REPLACE ( text , ' ' , ' ' ), ' ' , ' ' ), ' ' , ' ' ), ' ' , ' ' ), ' ' , ' ' ), ' ' , ' ' ), ' ' , ' ' ) ) LIKE ' %CREATE PROC% ' GROUP BY dbid, objectid ORDER BY SUM (total_elapsed_time) / SUM (usecounts) * 1.0 DESC ; - sys.dm_db_index_physical_stats
DBCC SHOWCONTIG was replaced by sys.dm_db_index_physical_stats. Under the covers though, they both use the same code - and the I/O characteristics haven't changed.
一些避免碎片的建议
- 创建数据库时,尽量为数据文件分配一个大的空间。你可以估计某一时期(比如至少3年)可能达到的最大值。
- 有时将数据文件设为自动增长是可行的。通过设置数据文件最大增长尺寸保持增量限制,在硬盘上保留一些可用空间。
- 一段时间后,如果需要,确定并重新估计数据库尺寸的最大值,为数据库添加更多的文件或者文件组。
- 如果有很多数据文件共用一个磁盘分区,别让数据文件自动增长。如果数据文件使用过多,那么将它们分配到不同的文件组或者磁盘。
- 定期执行数据库维护任务,如DBCC DBREINDEX、重新编译存储过程和触发器。
- 如果表的记录被频繁的修改或者删除,最好在该表上不定期的运行UPDATE STATISTICS,这将从执行计划里帮助避免性能降低。
SELECT
object_name(i.object_id)
as
object_name,i.
name
as
IndexName,ps.avg_fragmentation_in_percent,avg_page_space_used_in_percent
FROM
sys.dm_db_index_physical_stats (db_id(),
NULL
,
NULL
,
NULL
,
'DETAILED'
)
as
ps
INNER
JOIN
sys.indexes
as
i
ON
i.object_id = ps.object_id
AND
i.index_id = ps.index_id
WHERE
ps.avg_fragmentation_in_percent > 50
AND
ps.index_id > 0
ORDER
BY
1
object_name IndexName avg_fragmentation_in_percent avg_page_space_used_in_percent
----------- --------------------------------- ---------------------------- ------------------------------
Employee PK_Employee_EmployeeID 85.7142857142857 97.8679145045713
Employee AK_Employee_LoginID 66.6666666666667 66.5843093649617
Individual PK_Individual_CustomerID 87.5 61.851371386212
Individual XMLVALUE_Individual_Demographics 100 60.5339263652088
SELECT
*
FROM
sys.dm_db_index_physical_stats (DB_ID(N
'AdventureWorks'
), OBJECT_ID(N
'dbo.DatabaseLog'
),
NULL
,
NULL
,
'DETAILED'
);
--index_type_desc: HEAP,NON or CLUSTERED INDEX
--alloc_unit_type_desc: IN_ROW_DATA,LOB_DATA
--about index: index_depth, index_level
--about fragment: avg_fragmentation_in_percent,avg_fragment_size_in_pages
- IN_ROW_DATA包含除大型对象 (LOB) 数据以外的所有数据的数据行或索引行。页的类型为 Data 或 Index。
- LOB_DATA 以下列一种或多种数据类型存储的大型对象数据:text、ntext、image、xml、varchar(max)、nvarchar(max)、varbinary(max) 或 CLR 用户定义类型 (CLR UDT)。页的类型为 Text/Image。
- ROW_OVERFLOW_DATA 存储在超过 8,060 字节行大小限制的 varchar、nvarchar、varbinary 或 sql_variant 列中的可变长度数据。页的类型为 Text/Image。
- 拿到系统行为统计信息之后,你终于调整了索引,于是系统明显nb了。如果你要看看它变得有多nb,可以关注动态视图sys.dm_db_index_usage_stats
- 检测阻塞锁见 [MSSQL锁定-3.死锁与阻塞]
慢慢增加中..........
作者:Buro#79xxd出处:http://www.cnblogs.com/buro79xxd/文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。