諸々の理由で業務システムのデータベース製品にSQL Serverを使っており、そこで問題が起きた際に解析できるようのメモ。
RDS for SQL Server を使ってる場合
AWSのRDSでSQL Serverを使っている場合は、AWSネイティブの以下モニタリング機能を使うのがベター。
- 拡張モニタリング
- CPU使用率の内訳が見れる(idleやsys, usrなど)
- Performance Insight
- 時系列でロングランしているSQLや何で待機しているか等の情報が見れる
どちらもゼロダウンタイムで有効化ができる1。 GCPやAzureは調べてないが、Azureは少なくとも同様のモニタリング機能があるのではと想定。
調査用のSQL
クラウド・オンプレ関わらず、SQL Serverにログインできるのであれば、以下クエリで各種調査を行う。
所要時間が大きいSQL、CPU時間など
SQLの性能問題を解析する際は所要時間が大きいものから一般的には解析していくため、以下のSQLでトータルの所要時間を表す「TotalElapsedTime(sec)」をまず確認。 あわせて、CPU時間やIO回数などの情報も取得している。とりあえず所要時間だけ見たい際はコメントアウトするのが良い。
SELECT
TOP 100
t1.total_worker_time / t1.execution_count / 1000 as "avg cputime(ms)",
t1.max_worker_time /1000 as "max cputime(ms)",
t1.total_worker_time / 1000 as "total cputime(ms)",
t1.total_elapsed_time / 1000 as "TotalElapsedTime(sec)",
t1.total_logical_reads / t1.execution_count as "avg read count",
t1.max_logical_reads as "max read count",
t1.total_logical_reads as "total read count",
t1.execution_count as "exec count",
t2.text as "sql text",
t3.query_plan as "query plan"
FROM
sys.dm_exec_query_stats as t1
cross apply sys.dm_exec_sql_text(t1.sql_handle) as t2
outer apply sys.dm_exec_query_plan(t1.plan_handle) as t3
WHERE
t2.text NOT LIKE '%dm_exec_query_stats%'
ORDER BY
t1.total_worker_time DESC
;
ページサイズ・断片化情報
テーブルやIndexのオブジェクトが肥大化・断片化しているか確認する
SELECT
S.name AS 'schema name',
O.name AS 'table name',
IDX.name AS 'index name',
IDXPS.avg_fragmentation_in_percent AS 'fragmentation(%)',
IDXPS.page_count AS 'page count'
FROM
sys.dm_db_index_physical_stats (DB_ID(),null,null,null,null) AS IDXPS
LEFT OUTER JOIN sys.objects AS O ON IDXPS.object_id = O.object_id
LEFT OUTER JOIN sys.schemas AS S ON O.schema_id = S.schema_id
LEFT OUTER JOIN sys.indexes AS IDX ON IDXPS.object_id = IDX.object_id AND IDXPS.index_id = IDX.index_id
WHERE O.type = 'U'
AND IDX.index_id > 0
ORDER BY
IDXPS.avg_fragmentation_in_percent DESC
;