标签: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