Bob Ward の SQL Server 2022 Hidden Gems で解説されているのですが、SQL Server 2022 ならびに Azure SQL Database では、query_antipattern という拡張イベントが追加されています。
MS のブログでも紹介されており、最近、新しい記事も公開されました。
- Watch out for performance problems due to antipattern queries in SQL
- Lesson Learned #367: Query Antipattern and Ring Buffer in Azure SQL Database
この拡張イベントについて、本ブログでも触れておきたいと思います。
取得可能なアンチパターン
SQL Server のクエリ実行ではいくつかのアンチパターンがあります。そのなかで次のパターンが実行されているかを取得することができるのが、拡張イベントの query_antipattern になります。
どのようなパターンが検知できるかは次のクエリで確認できます。型変換により Seek が阻害されているものと IN 句に大量の条件が含まれているものが検知できるのは、実運用でも嬉しいパターンかもしれませんね。
select * from sys.dm_xe_map_values where name = 'query_antipattern_type' order by map_key
- TypeConvertPreventingSeek
- NonOptimalOrLogic
- LargeIn
- LargeNumberOfOrInPredicate
- Max
上記のパターンに合致するクエリが実行されると、次のように拡張イベントに情報が取得され、どのようなクエリがどのアンチパターンで検知されたのかを確認することができます。
拡張イベントを取得する際には、イベント取得のオーバーヘッドが気になることがあるかと思います。SQL Server 2022 / Azure SQL Database では sys.dm_xe_session_events / sys.dm_xe_database_session_events という拡張イベントを使用することができます。
この拡張イベントを使用すると、イベントの発行にかかった時間を取得することができます。
select es.name, se.* from sys.dm_xe_session_events AS se inner join sys.dm_xe_sessions AS es on se.event_session_address = es.address where event_name = 'query_antipattern'
最新の SQL Server であれば、拡張イベントを追加した際には、この DMV を使用してイベント取得のオーバーヘッドを確認してみると良いのではないでしょうか。