标签:ace eth where 查看 arc else alt alter 注意
通过上一节收集的数据组合在一起,并经过分析阶段,制定出对索引的创建、删除、修改方案,然后在实施阶段进行部署
主要关注下面几个部分:
1.审查服务器状态
2.未使用索引
3.索引计划使用
一:审查服务器状态
1.性能计数器
2.等待信息
3.Buffer分配
Use IndexDemo WITH CounterSummary AS ( SELECT create_date ,server_name ,MAX(CASE WHEN counter_name = ‘Forwarded Records/sec‘ THEN Calculated_Counter_value END) ForwardedRecords ,MAX(CASE WHEN counter_name = ‘Forwarded Records/sec‘ THEN Calculated_Counter_value END) / (NULLIF(MAX(CASE WHEN counter_name = ‘Batch Requests/sec‘ THEN Calculated_Counter_value END),0) * 10) AS ForwardedRecordRatio FROM dbo.IndexingCounters WHERE counter_name IN (‘Forwarded Records/sec‘,‘Batch Requests/sec‘) GROUP BY create_date ,server_name ) SELECT server_name ,MIN(ForwardedRecords) AS MinForwardedRecords ,AVG(ForwardedRecords) AS AvgForwardedRecords ,MAX(ForwardedRecords) AS MaxForwardedRecords ,MIN(ForwardedRecordRatio) AS MinForwardedRecordRatio ,AVG(ForwardedRecordRatio) AS AvgForwardedRecordRatio ,MAX(ForwardedRecordRatio) AS MaxForwardedRecordRatio ,100.*SUM(CASE WHEN ForwardedRecordRatio > 1 THEN 1 END) /COUNT(*) AS PctViolation FROM CounterSummary GROUP BY server_name
创建一个堆表,插入数据,并更新其中一些数据,引发堆分页,最后执行上面的查询检查情况
USE IndexDemo GO IF OBJECT_ID(‘HeapExample‘, ‘U‘) IS NOT NULL DROP TABLE HeapExample CREATE TABLE dbo.HeapExample ( ID INT IDENTITY , FillerData VARCHAR(2000) ) INSERT INTO dbo.HeapExample ( FillerData ) SELECT REPLICATE(‘X‘, 100) FROM sys.all_objects UPDATE dbo.HeapExample SET FillerData = REPLICATE(‘X‘, 2000) WHERE ID % 5 = 1 GO SELECT * FROM dbo.HeapExample WHERE ID % 3 = 1
当Forwarded Records发生,再次执行代码
如果存在Forward Records问题,通常有3种解决方案
1.更改数据类型,把变长改成定长,如varchar-char,不够这种情况可能不是很通用,而且可能伴随数据截断等问题
2.改变表的存储结构,也就是创建一个聚集索引在上面,从而移除堆表的组织数据机制
3.就是重建堆表
ALTER TABLE dbo.HeapExample REBUILD
2.Access Methods\FreeSpace Scans/sec(关于堆表的另一个计数器)
当在堆表中插入数据时,他会标识发生了什么操作,在插入过程中,可能会引起GAM、SGAM和PFS页的改动。如果插入的频率足够高,可能会在这些页上产生争用
通过汇总最小值、平均值和最大值来进行分析
WITH CounterSummary AS ( SELECT create_date , server_name , MAX(CASE WHEN counter_name = ‘FreeSpace Scans/sec‘ THEN Calculated_Counter_value END) FreeSpaceScans , MAX(CASE WHEN counter_name = ‘FreeSpace Scans/sec‘ THEN Calculated_Counter_value END) / ( NULLIF(MAX(CASE WHEN counter_name = ‘Batch Requests/sec‘ THEN Calculated_Counter_value END), 0) * 10 ) AS ForwardedRecordRatio FROM dbo.IndexingCounters WHERE counter_name IN ( ‘FreeSpace Scans/sec‘, ‘Batch Requests/sec‘ ) GROUP BY create_date , server_name ) SELECT server_name , MIN(FreeSpaceScans) AS MinFreeSpaceScans , AVG(FreeSpaceScans) AS AvgFreeSpaceScans , MAX(FreeSpaceScans) AS MaxFreeSpaceScans , MIN(ForwardedRecordRatio) AS MinForwardedRecordRatio , AVG(ForwardedRecordRatio) AS AvgForwardedRecordRatio , MAX(ForwardedRecordRatio) AS MaxForwardedRecordRatio , 100. * SUM(CASE WHEN ForwardedRecordRatio > 1 THEN 1 END) / COUNT(*) AS PctViolation FROM CounterSummary GROUP BY server_name
如果FreeSpace Scans/sec很高,应该集中分析哪个堆有最高的插入数率。可以使用:sys.dm_db_index_operational_stats来查找
SELECT QUOTENAME(DB_NAME(database_id)) AS database_name , QUOTENAME(OBJECT_SCHEMA_NAME(object_id, database_id)) + ‘.‘ + QUOTENAME(OBJECT_NAME(object_id, database_id)) AS ObjectName , SUM(leaf_insert_count) AS leaf_insert_count , SUM(leaf_allocation_count) AS leaf_allocation_count FROM dbo.index_operational_stats_history WHERE index_id = 0 AND database_id > 4 GROUP BY object_id , database_id ORDER BY leaf_insert_count DESC
在查找到根源之后,最好的方法就是加上聚集索引,改变其数据组织机制
3.Access Methods\Full Scans/sec,通过这个计数器可查看Full Scans/sec的值,这个值包含聚集、非聚集索引及堆表。高值意味着查询存在性能问题,这种情况可能会引起Page Life Expectancy(用于衡量内存压力的一个主要计数器)的变动,这将加大数据在内存中的存储时间,并引起I/O问题
下面的脚本用于分析当前Full Scans/sec的值,同样也需要考虑Batch Requests/sec 计数器,如果这两个值的比例超过1000,就需要引起注意
WITH CounterSummary AS ( SELECT create_date , server_name , MAX(CASE WHEN counter_name = ‘Full Scans/sec‘ THEN Calculated_Counter_value END) FullScans , MAX(CASE WHEN counter_name = ‘Full Scans/sec‘ THEN Calculated_Counter_value END) / ( NULLIF(MAX(CASE WHEN counter_name = ‘Batch Requests/sec‘ THEN Calculated_Counter_value END), 0) * 1000 ) AS FullRatio FROM dbo.IndexingCounters WHERE counter_name IN ( ‘Full Scans/sec‘, ‘Batch Requests/sec‘ ) GROUP BY create_date , server_name ) SELECT server_name , MIN(FullScans) AS MinFullScans , AVG(FullScans) AS AvgFullScans , MAX(FullScans) AS MaxFullScans , MIN(FullRatio) AS MinFullRatio , AVG(FullRatio) AS AvgFullRatio , MAX(FullRatio) AS MaxFullRatio , 100. * SUM(CASE WHEN FullRatio > 1 THEN 1 ELSE 0 END) / COUNT(*) AS PctViolation FROM CounterSummary GROUP BY server_name
4. Access Methods\Index Searches/sec,大部分情况下,索引查找会比索引扫描有效,这个计数器显示SQL Server 实例上发生索引查找的比率,这个值相对于Full Scans/sec来说越高越好。这个比率是衡量索引是否有效的标准之一,这两个值的比率一般是1000:1
WITH CounterSummary AS ( SELECT create_date , server_name , MAX(CASE WHEN counter_name = ‘Index Searches/sec‘ THEN Calculated_Counter_value END) IndexSearches , MAX(CASE WHEN counter_name = ‘Index Searches/sec‘ THEN Calculated_Counter_value END) / ( NULLIF(MAX(CASE WHEN counter_name = ‘Full Scans/sec‘ THEN Calculated_Counter_value END), 0) * 1000 ) AS SearchToScanRatio FROM dbo.IndexingCounters WHERE counter_name IN ( ‘Index Searches/sec‘, ‘Full Scans/sec‘ ) GROUP BY create_date , server_name ) SELECT server_name , MIN(IndexSearches) AS MinIndexSearches , AVG(IndexSearches) AS AvgIndexSearches , MAX(IndexSearches) AS MaxIndexSearches , MIN(SearchToScanRatio) AS MinSearchToScanRatio , AVG(SearchToScanRatio) AS AvgSearchToScanRatio , MAX(SearchToScanRatio) AS MaxSearchToScanRatio , 100. * SUM(CASE WHEN SearchToScanRatio > 1 THEN 1 END) / COUNT(*) AS PctViolation FROM CounterSummary GROUP BY server_name
标签:ace eth where 查看 arc else alt alter 注意
原文地址:https://www.cnblogs.com/sunliyuan/p/9033221.html