推測ではなく証拠から始める
性能チューニングは順序の問題です。エンジンがlocks、memory grants、log flushes、I/O待機に多くの時間を使っているなら、その事実を基準に後続の判断を行う必要があります。支配的なボトルネックと、それを生むstatementを特定せずに個別最適化を始めるのが、最も早い時間の無駄です。
実務ルール: チューニング計画が全インデックス再構築から始まるなら、診断段階を飛ばしています。
SQL Server ??????????????????
?????????????????????????????????????????????????????????? statement ??????
wait statistics ?????
sql???????????????????? SQL Server ???????????????????????????
SELECT TOP (10)
wait_type,
waiting_tasks_count,
wait_time_ms / 1000.0 AS wait_time_seconds,
max_wait_time_ms / 1000.0 AS max_wait_seconds,
signal_wait_time_ms / 1000.0 AS signal_wait_seconds
FROM sys.dm_os_wait_stats
WHERE wait_type NOT LIKE 'SLEEP%'
AND wait_type NOT IN ('CLR_SEMAPHORE', 'LAZYWRITER_SLEEP', 'XE_TIMER_EVENT')
ORDER BY wait_time_ms DESC; ?????????????????
sql??????????????????????????????????????????????
UPDATE STATISTICS dbo.SalesOrderHeader
WITH FULLSCAN;
SELECT
s.name AS stats_name,
sp.last_updated,
sp.rows,
sp.rows_sampled,
sp.modification_counter
FROM sys.stats AS s
CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) AS sp
WHERE s.object_id = OBJECT_ID('dbo.SalesOrderHeader')
ORDER BY sp.last_updated DESC; plan cache ?????? statement ?????
sql??????? stored procedure ??????????????????????????????
SELECT TOP (20)
qs.execution_count,
qs.total_worker_time / 1000 AS total_cpu_ms,
qs.total_elapsed_time / 1000 AS total_duration_ms,
qs.total_logical_reads,
qs.total_logical_writes,
DB_NAME(st.dbid) AS database_name,
OBJECT_NAME(st.objectid, st.dbid) AS object_name,
SUBSTRING(
st.text,
(qs.statement_start_offset / 2) + 1,
(
(CASE qs.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
ORDER BY qs.total_worker_time DESC; 実践的な最適化シーケンス
最初にwaitと主要消費者を見る
構成や保守を変える前に、waitカテゴリ、重いクエリ、memory grant、CPU圧力、高I/Oのstatementを確認します。
古い統計を修正する
大規模テーブルや偏った分布ではauto-updateだけでは足りません。行変更パターンを確認し、推定が明らかに誤っている箇所を更新します。
断片化だけでなくインデックス戦略を見る
欠けたカバレッジ、重複、未使用、過度に広い定義を洗い出してからrebuildかreorganizeかを決めます。
実行計画とパラメータ感度を調べる
誤った推定、不適切なjoin、spill、暗黙変換、parameter sniffingは、全体設定よりも問題の説明力が高いことが多いです。
TempDB、メモリ、I/Oを一体で見る
spill、version store、latch contention、ログ圧力、ストレージ遅延は相互に影響します。1点だけ直すと本当のボトルネックを隠すことがあります。
実務で確認すべきこと
クエリと統計のレビュー
- - 現在の瞬間値だけでなく、時間と傾向で見たtop waits
- - CPU、read、duration、execution数が大きいstatement
- - データ変化で推定が崩れたテーブル
- - scan、spill、暗黙変換、不適切なjoinを含むプラン
運用面と物理面のレビュー
- - 不足、重複、未使用、重なりのあるインデックス
- - TempDB設計、version store負荷、spillパターン
- - memory grant、buffer圧力、checkpointやlog writeの挙動
- - ストレージ遅延、growth設定、保守時間帯への圧力
SQL Server運用でAIが役立つ場面
AIはチューニングの基礎を置き換えませんが、変化を早く検知し、調査の優先順位付けに役立ちます。
ワークロード異常検知
テレメトリパターンを使い、wait、throughput、latencyの急変をユーザー報告前に検知します。
容量予測
I/O、ストレージ、同時実行の成長をモデル化し、レポート周期や新機能の前に計画できます。
運用トリアージ
繰り返す症状を束ね、可能性の高い要因を要約し、アラートから確認すべき少数のクエリと資源までの距離を縮めます。
正しい順序でシステムを最適化する
重要なのは順序です。waitは時間の消失先を示します。統計はオプティマイザに十分な情報があったかを示します。インデックスレビューはアクセスパスがワークロードを支えているかを示します。プラン、TempDB、メモリ、I/Oは、そのパスを実行するコストが高すぎないかを示します。
この順序を守ると、チューニングは再現可能になり、勘への依存が減ります。SQL Serverの性能改善が儀式ではなくエンジニアリングプロセスになる理由はそこにあります。
関連するSQL Server記事
運用カバレッジにはサービスガイドを、分析テーブル設計にはcolumnstoreガイドを使ってください。
FAQ
SQL Serverが遅いとき、最初に何を見るべきですか?
まずwait、最も資源を消費するクエリ、最近のワークロード変化を確認します。その後でインデックス、パラメータ、ハードウェアを変更すべきです。
SQL Serverの統計はどのくらいの頻度で更新すべきですか?
全システム共通の頻度はありません。大きなテーブルや偏った分布では、重要なデータ変化後に狙った更新が必要なことがあります。
インデックス断片化は性能低下の主因ですか?
多くの場合そうではありません。欠けたカバレッジ、悪いキー順、重複インデックス、誤推定、パラメータ感度、TempDBやI/Oのボトルネックの方が重要です。