web-dev-qa-db-ja.com

この頻繁なSQLがSQL Serverプロシージャキャッシュにないのはなぜですか?

SQL Serverプロシージャキャッシュ(dm_exec_query_statsdm_exec_sql_textdm_exec_query_plan)実行統計と実行計画を取得します。

新しいアプリケーション(新しい開発チームなど)があり、そのSQLがプロシージャキャッシュに表示されていません。

  • キャッシュには、Ideraおよび内部SQL ServerプロセスからのSQLがあります。
  • Ideraは、アプリケーションから長時間実行されているSQLを報告しています。
  • アクティビティモニターのセッションでアプリケーションSQLを確認できます。

しかし、このアプリケーションのプロシージャキャッシュには何もありません。だから私はほとんど盲目です。
これはSQL Server 2017ですが、他のSQL Server 2017データベースではこの問題は発生しません。
このアプリケーションは.Net(Core .Net SqlClient Data Providerを使用して接続)であり、ほとんどのアプリケーションがJava、Tomcat、JDBCを使用しているため、これは少し奇妙です。

RECOMPILEヒント/オプションはSQLをプロシージャキャッシュに保存しないという記事を見てきました。開発チームが意図的にそうしているとは思いません。それを強制しているプロバイダーに設定がある可能性はありますか?

誰もがこれについて調査の道を提案できますか?

2
Mike Tefft

Core .Net SqlClientデータプロバイダー(別名_System.Data.SqlClient_)には、プランのキャッシュを明示的に防ぐものはありません。

プランのキャッシュを確認するために実行しているクエリを正確に把握しておくと役立ちます。

たとえば、開発者がクエリをパラメーター化しているかどうかに応じて、_sys.dm_exec_cached_plans_のエントリに異なるobjtype値が表示されることがあります。

  • 「準備済み」-クエリには、SqlParameterクラスを使用して追加されたパラメーターがありました
  • 「アドホック」-クエリにパラメータがなかったか、パラメータがクエリテキストに直接埋め込まれました

しかし、私はそれが他のデータプロバイダーにも当てはまることを期待しています。

SQL Server 2017を使用しているので、このデータベースに対してクエリストアを有効にして、予想されるSQLテキストがそこでキャプチャされているかどうかを確認することもできます。これには、OPTION (RECOMPILE)を使用するクエリも含まれます(詳細については、Erin Stellatoのブログ投稿 OPTION(RECOMPILE)を使用したクエリとクエリストア を参照してください)。これは、開発者がそのヒントを使用しているかどうかを確認するのに役立ちます。

最後に、拡張イベントを使用して、アプリケーションの実行中に実行中のクエリを一時的にキャプチャできます。これを行う非常に簡単な方法は Erik Darling's _sp_HumanEvents_ を使用することです。これは、20秒間実行されるサイトからの使用例であり、少なくとも1秒間実行された「YourDatabaseName」データベースに対するすべてのクエリをキャプチャします。

_EXEC dbo.sp_HumanEvents 
    @event_type = 'query', 
    @query_duration_ms = 1000, 
    @seconds_sample = 20, 
    @database_name = 'YourDatabaseName';
_
2
Josh Darnell