SQL Server性能分析與優化
概述
本文主要介紹使用阿里云ECS實例搭建并使用SQL Server時,SQL Server性能相關的分析與優化。
詳細信息
阿里云提醒您:
如果您對實例或數據有修改、變更等風險操作,務必注意實例的容災、容錯能力,確保數據安全。
如果您對實例(包括但不限于ECS、RDS)等進行配置與數據修改,建議提前創建快照或開啟RDS日志備份等功能。
如果您在阿里云平臺授權或者提交過登錄賬號、密碼等安全信息,建議您及時修改。
請根據現場實際情況,參考以下對應的解決方案。
前提條件
在進行系統服務排查之前,需滿足以下條件:
系統登錄使用正常,無明顯系統故障。
性能監控工具正常。
在性能分析之前,由于相關分析需要依賴緩存數據,請確保相關數據未清理。
排查項目
SQL Server整體性能分析。
SQL Server慢SQL分析。
SQL Server CPU/內存/IO分析。
排查方案
SQL Server整體性能分析
使用“性能監視器”查看使用情況。
Processor 查看CPU性能。
PhysicalDisk 查看IO情況。
Memory 查看內存情況。
SQLServer:Plan Cache 查看高速緩存使用情況。
SQLServer:Transactions 查看大事務使用情況。
SQLServer:Databases 查看數據庫整體分析情況。
SQLServer:Database Mirroring 查看鏡像同步情況。
SQLServer:Buffer Manager 查看內存使用情況。
SQLServer:Latches 查看Latches使用情況。
SQLServer:Locks 查看Locks使用情況。
SQLServer:Wait Statistics 查看資源等待情況。
查看sys.sysprocesses視圖分析等待類型。
查看sys.dm_db_index_physical_stats視圖,分析索引碎片率。
SQL Server慢SQL分析
sys.dm_exec_query_stats 查看查詢緩存的統計信息。
sys.dm_exec_sql_text 查看緩存查詢SQL。
sys.dm_exec_query_plan 查看緩存查詢計劃。
SQL Server CPU/內存/IO分析
sys.dm_os_wait_stats 查看等待資源統計信息。
sys.dm_os_buffer_descriptors 查看對象緩存計數情況。
sys.dm_os_performance_counters 查看內存命中率。
sys.dm_io_virtual_file_stats 查看IO使用情況。
優化建議
索引碎片率大,影響查詢的速度。如果索引碎片率在5%-30%之間,推薦重組索引;如果碎片率大于30%,推薦重建索引。
根據TOP SQL提供優化建議。
排查步驟
查看整體主機性能數據
通過性能監視器可以看到內存、磁盤、CPU使用情況。
查看當前進程執行情況
select * from sys.sysprocesses where spid > 50;
查看CPU使用高的 TOP SQL
SELECT TOP 50
[Avg. MultiCore/CPU time(sec)] = qs.total_worker_time / 1000000 / qs.execution_count,
[Total MultiCore/CPU time(sec)] = qs.total_worker_time / 1000000,
[Avg. Elapsed Time(sec)] = qs.total_elapsed_time / 1000000 / qs.execution_count,
[Total Elapsed Time(sec)] = qs.total_elapsed_time / 1000000,
qs.execution_count,
[Avg. I/O] = (total_logical_reads + total_logical_writes) / qs.execution_count,
[Total I/O] = total_logical_reads + total_logical_writes,
Query = SUBSTRING( qt.[text],
(qs.statement_start_offset / 2) + 1,
((CASE qs.statement_end_offset
WHEN -1 THEN
DATALENGTH(qt.[text])
ELSE
qs.statement_end_offset
END - qs.statement_start_offset
) / 2
) + 1
),
Batch = qt.[text],
[DB] = DB_NAME(qt.[dbid]),
qs.last_execution_time,
qp.query_plan
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.[sql_handle]) AS qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) AS qp
WHERE qs.execution_count > 5; --more than 5 occurences ORDER BY [Total MultiCore/CPU time(sec)] DESC;
查看每個數據庫的緩存頁計數
SELECT COUNT(*) * 8 / 1024 AS 'cache size(MB)',
CASE database_id
WHEN 32767 THEN
'ResourceDb'
ELSE
DB_NAME(database_id)
END AS 'datebase'
FROM sys.dm_os_buffer_descriptors
GROUP BY DB_NAME(database_id),
database_id
ORDER BY 'cache size(MB)' DESC;
SELECT COUNT(*)AS cached_pages_count
,CASE database_id
WHEN 32767 THEN 'ResourceDb'
ELSE db_name(database_id)
END AS database_name
FROM sys.dm_os_buffer_descriptors
GROUP BY DB_NAME(database_id) ,database_id
ORDER BY cached_pages_count DESC;
查看緩存命中率情況
SELECT counter_name AS CounterName,
(a.cntr_value * 1.0 / b.cntr_value) * 100.0 AS BufferCacheHitRatio
FROM sys.dm_os_performance_counters a
JOIN
(
SELECT cntr_value,
object_name
FROM sys.dm_os_performance_counters
WHERE counter_name = 'Buffer cache hit ratio base'
AND object_name LIKE '%Buffer Manager%'
) b
ON a.object_name = b.object_name
WHERE a.counter_name = 'Buffer cache hit ratio'
AND a.object_name LIKE '%Buffer Manager%';
查看數據庫IO使用情況
SELECT DB_NAME(fs.database_id) AS [Database Name],
CAST(fs.io_stall_read_ms / (1.0 + fs.num_of_reads) AS NUMERIC(10, 1)) AS [avg_read_stall_ms],
CAST(fs.io_stall_write_ms / (1.0 + fs.num_of_writes) AS NUMERIC(10, 1)) AS [avg_write_stall_ms],
CAST((fs.io_stall_read_ms + fs.io_stall_write_ms) / (1.0 + fs.num_of_reads + fs.num_of_writes) AS NUMERIC(10, 1)) AS [avg_io_stall_ms],
CONVERT(DECIMAL(18, 2), mf.size / 128.0) AS [File Size (MB)],
mf.physical_name,
mf.type_desc,
fs.io_stall_read_ms,
fs.num_of_reads,
fs.io_stall_write_ms,
fs.num_of_writes,
fs.io_stall_read_ms + fs.io_stall_write_ms AS [io_stalls],
fs.num_of_reads + fs.num_of_writes AS [total_io],
io_stall_queued_read_ms AS [Resource Governor Total Read IO Latency (ms)],
io_stall_queued_write_ms AS [Resource Governor Total Write IO Latency (ms)]
FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS fs
INNER JOIN sys.master_files AS mf WITH (NOLOCK)
ON fs.database_id = mf.database_id
AND fs.[file_id] = mf.[file_id]
ORDER BY avg_io_stall_ms DESC
OPTION (RECOMPILE);