web-dev-qa-db-ja.com

拡張イベントフィルターのパフォーマンスへの影響[like_i_sql_unicode_string]

Nolockヒントを使用してすべてのクエリを表示したい拡張イベントセッションを作成しました。パフォーマンスへの影響を最小限に抑えるために、SQLトレースの代わりに使用することにしました。セッションは次のステートメントのように作成されました:

    CREATE EVENT SESSION [SCOMDB_debug] ON SERVER 
    ADD EVENT sqlserver.deprecation_announcement(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)),
    ADD EVENT sqlserver.rpc_completed(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.rpc_starting(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.sp_statement_completed(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.sp_statement_starting(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.sql_batch_completed(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.sql_batch_starting(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.sql_statement_completed(
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))),
    ADD EVENT sqlserver.sql_statement_starting(SET collect_statement=(1)
        ACTION(sqlserver.client_hostname,sqlserver.database_name,sqlserver.nt_username,sqlserver.session_id,sqlserver.sql_text,sqlserver.transaction_id,sqlserver.username)
        WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%NOLOCK%'))) 
    ADD TARGET package0.event_file(SET filename=N'M:\MSSQL11.SCOMDB\MSSQL\Log\SCOMDB_debug.xel',max_file_size=(500))
    WITH (MAX_MEMORY=40960 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
    GO

その結果、データベースインスタンス(SCOMデータベースに使用)が非常に遅くなり、アプリケーションはほとんど使用できなくなりました。

待機統計にはSOS_SCHEDULER_YIELDとPREEMPTIVE_XE_DISPATCHERがいっぱいで、CPUでほとんど待機しているsys.dm_exec_requestsで長時間実行されている多くのクエリも確認できました。

それは期待される行動ですか? [like_i_sql_unicode_string]演算子はパフォーマンスをかなり消費する可能性があると想像できますが、それでもはるかに優れたパフォーマンスが期待されます。

「sometext」を含むクエリをキャッチするために使用できるexイベントの他のフィルターはありますか?

5
dewet

すべてのstartイベントは必要ありません。completedだけが必要です。 SCOMデータベースのためだけにデータをキャプチャしているようにも見えません。 拡張イベントは、SQL Serverトレースのすぐ近くにオーバーヘッドを引き起こす可能性があります キャプチャしようとしているものによって異なります。

基本的には、サーバー全体で発生するすべてのクエリをキャプチャし、待機するように指示するので、最初にクエリのテキストを確認してから、拡張イベントセッションを通じて情報を取得し、それを完了させます。

同様に、SCOMの一定のアクティビティは、環境の構成に応じて、トレースイベントまたは拡張イベントのいずれかでパフォーマンスが極端に低下する可能性があります。最初に、これらのタイプのクエリのプランキャッシュを確認することをお勧めします。ただし、アクティブなセッションからデータのサンプルを取得するだけで、特定のデータベースのデータのみを取得するなど、セッションにさらにフィルターを追加することもできます。 GUIからは次のようになります。

enter image description here

または、WHERE句を次のようにコーディングします。

WHERE ((([package0].[divides_by_uint64]([sqlserver].[session_id],(5))) 
   AND ([package0].[greater_than_uint64]([sqlserver].[database_id],(4)))) 
   AND ([package0].[equal_boolean]([sqlserver].[is_system],(0))))) 

これにより、そのデータベースのアクティブなセッションの20%をいつでも取得できると思います。ただし、すべてのイベントが必要な場合は、そのアクションのオーバーヘッドに苦しむ必要があります。

それがマイクロソフト製品であるので、私はそれがどのクエリを生成しているのか気にする必要はありません。パフォーマンスの問題が発生している場合は、製品のMicrosoftガイドラインに従うか、Microsoftサポートに問い合わせてください。

4
user507