SQL Server 2008 R2 に対して実行されている Entity Framework (4.2) によって生成された単純な SQL クエリで、重大なパフォーマンスの問題が発生しています。一部の状況 (すべてではない) では、EF は次の構文を使用します。
exec sp_executesql 'DYNAMIC-SQL-QUERY-HERE', @param1...
他の状況では、提供されたパラメーターをクエリに焼き付けて生の SQL を実行するだけです。私が遭遇している問題は、sp_executesql で実行されたクエリがターゲット テーブルのすべてのインデックスを無視しているため、クエリのパフォーマンスが非常に低下していることです (SSMS で実行プランを調べることで確認されています)。
少し調査した結果、この問題は「パラメータ スニッフィング」が原因である可能性があるようです。OPTION(RECOMPILE) クエリ ヒントを追加すると、次のようになります。
exec sp_executesql 'DYNAMIC-SQL-QUERY-HERE OPTION(RECOMPILE)', @param1...
ターゲット テーブルのインデックスが使用され、クエリは非常に高速に実行されます。また、データベース インスタンス ( http://support.microsoft.com/kb/980653 ) でパラメーター スニッフィング (4136) を無効にするために使用されるトレース フラグを切り替えようとしましたが、これはまったく効果がないようです。
これにより、いくつかの質問が残ります。
- Entity Framework によって生成された SQL に OPTION(RECOMPILE) クエリ ヒントを追加する方法はありますか?
- Entity Framework が exec sp_executesql を使用するのを防ぎ、代わりに生の SQL を実行する方法はありますか?
- 他の誰かがこの問題に遭遇していますか? 他のヒント/ヒントはありますか?
追加情報:
- SSMS を介してデータベース インスタンスを再起動しましたが、サービス管理コンソールからサービスを再起動してみます。
- パラメータ化は SIMPLE に設定されます (is_parameterization_forced: 0)
- アドホック ワークロードの最適化には、次の設定があります。
- 値: 0
- 最小: 0
- 最大: 1
- 使用中の値: 0
- is_dynamic: 1
- is_advanced: 1
また、以下のスクリプトでトレース フラグ 4136 を有効にした後、サービス管理コンソールを介して SQL Server サービスを再起動すると、実際にはトレース フラグがクリアされているように見えることにも言及する必要があります...おそらく、これを別の方法で行う必要があります...
DBCC TRACEON(4136,-1)