蒼の王座 さんの Azure SQL Database で待ち事象を調査する「sys.dm_db_wait_stats」を読んで、久しぶりに Azure SQL Database (旧 SQL Azure) を使ってみました。
今回追加された sys.dm_db_wait_stats ですが、まだ System Views (Windows Azure SQL Database) には追加されていないようですが、最初に紹介した蒼の王座さん以外では以下のブログなので紹介がされています。
SQL Database WAIT STATS
New DMO in Azure SQL Database: sys.dm_db_wait_stats
オンプレミスの SQL Server では 2005 以降で実装されていた sys.dm_os_wait_stats の Aure SQL Database 版となります。
この動的管理ビューでは SQL Server で発生している各種待ち状態の累積値を取得することができます。
累積値という形で情報が収集されているため、SQL Server のサービスが最後に稼働してからの累積情報となります。
# DBCC SQLPERF でクリアをしていない場合ですが。
オンプレミスの SQL Server の場合は、インスタンス単位での情報取得となっていたのですが、Azure SQL Database では接続しているデータベース単位での情報取得となります。
軽く使ってみたところ SQL Server と Azure SQL Database の違いとしては、
- Azure SQL Database では発生した待ちの情報のみが取得できる
# 発生していない待ちは取得できないようです - ユーザーが任意にクリアすることができない
# SQL Server は DBCC SQLPERF(N’sys.dm_os_wait_stats’, CLEAR) とするとクリアできる
というようなことがありそうです。
以下は Azure SQL Database にデータベースを作成した直後の待ち事象の情報となります。
こちらが SQL Server で取得した初期状態の待ち事象の方法です。
取得できるカラムは同じですが、 SQL Server ではずらっと情報が取得されていることが確認できます。
Azure SQL Database でいくつかのクエリを実行して待ちを発生させた状態がこちらになります。
SQL Server ではすべての待ち事象についての情報が取得されていますが、Azure SQL Database に関しては発生した待ち事象のみが取得できるようになるようですね。
また、SQL Server では稼働しているだけで待ち時間が上昇する待ち事象がいくつかあります。
代表的なものとしては以下のようなものになります。
これらは、SQL Server が起動していると何も処理をしなくても上昇していくのですが、Azure SQL Database では恒常的に上昇しているものは取得されていませんでしたのでこの辺は制御がされているようですね。
# 特定の DB に対して発生した待ち事象が拡張イベントのようなものを使用して集計されているのかもしれないですね。
蒼の王座さんのブログでも紹介されていますが、Azure SQL Database では DBCC コマンドが制限がかかっており、DBCC SQLPERF(N’sys.dm_db_wait_stats’, CLEAR) で待ち事象のクリアをすることができません。
そのため、特定期間の待ち状態を確認するためには計測したい期間の最初と最後で sys.dm_db_wait_stats の情報を取得して差を出す必要があります。
セッションが切れなければ WAITFOR TIME でクエリをかけ逃げするということもできるかもしれないですね。
# Azure SQL Database の日付は UTC なので注意が必要なのとある程度の時間でセッションが切られると思いますので使えない気がかなりしますが。オンプレミスの環境で席にいない時間帯の待ち事象を期間でとりたい場合はこの方法を使ってかけ逃げしたりするのですが。
これらの待ち事象を簡単に解説してみると、
wait_type | 待ちの発生原因 |
LCK_M_xx | ロックの競合 |
PAGEIOLATCH_xx | ディスクからのデータ取得によるラッチの発生 |
ASYNC_NETWORK_IO | 実行した SQL の結果セットをクライアントに返している間のネットワーク通信 |
SOS_SCHEDULER_YIELD | SQL OS のスケジューラー間の譲渡 (CPU の割り当て待ち) |
WRITELOG | トランザクションログの書き込み |
SE_REPL_xx | Azure SQL Database の冗長構成の複製のための待ち |
というところでしょうか。
SE_REPL_COMMIT_ACK に関しては、最近 Windows Azure SQL Database and SQL Server — Performance and Scalability Compared and Contrasted という技術文書でも紹介されていますね。
昔、SQL Azure のデータ更新時に発生する待ち事象を確認してみる というようなことをして取得していたのが懐かしいです。
Azure SQL Database を使用していて、今後のパフォーマンス改善をしようと思った際にこれらの情報はかなり有益になると思いますので Azure SQL Database の運用をしている場合は時間があるときに見ておくと DB の利用傾向がわかってよいかもしれないですね。