24

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) を無効にするために使用されるトレース フラグを切り替えようとしましたが、これはまったく効果がないようです。

これにより、いくつかの質問が残ります。

  1. Entity Framework によって生成された SQL に OPTION(RECOMPILE) クエリ ヒントを追加する方法はありますか?
  2. Entity Framework が exec sp_executesql を使用するのを防ぎ、代わりに生の SQL を実行する方法はありますか?
  3. 他の誰かがこの問題に遭遇していますか? 他のヒント/ヒントはありますか?

追加情報:

  1. SSMS を介してデータベース インスタンスを再起動しましたが、サービス管理コンソールからサービスを再起動してみます。
  2. パラメータ化は SIMPLE に設定されます (is_parameterization_forced: 0)
  3. アドホック ワークロードの最適化には、次の設定があります。
    • 値: 0
    • 最小: 0
    • 最大: 1
    • 使用中の値: 0
    • is_dynamic: 1
    • is_advanced: 1

また、以下のスクリプトでトレース フラグ 4136 を有効にした後、サービス管理コンソールを介して SQL Server サービスを再起動すると、実際にはトレース フラグがクリアされているように見えることにも言及する必要があります...おそらく、これを別の方法で行う必要があります...

DBCC TRACEON(4136,-1)
4

2 に答える 2

8

tl;dr

update statistics


1 つのパラメーター (主キー) を持つdeleteクエリがあり、EF とsp_executesql. 最初の引数にパラメータを埋め込んでクエリを手動で実行しsp_executesql、クエリをすばやく実行します (~0.2 秒)。追加option (recompile)も機能しました。もちろん、EF を使用していたため、これら 2 つの回避策は利用できません。

おそらく外部キー制約のカスケードが原因で、実行時間の長いクエリの実行計画は、うーん...巨大でした。SSMS で実行計画を確認したところ、場合によっては異なるステップ間の矢印が他のものよりも幅が広いことに気付きました。これは、SQL Server が適切な決定を下すのに問題があったことを示している可能性があります。それが統計について考えるきっかけになりました。実行計画のステップを調べて、疑わしいステップに関与しているテーブルを確認しました。それから私はupdate statistics Tableそのテーブルに走りました。次に、悪いクエリを再実行しました。そして、もう一度やり直しました。そしてもう一度確認するために。出来た。パフォーマンスは正常に戻りました。(それでも、非パフォーマンスよりはやや悪いですsp_executesqlが、ちょっと!)

これは開発環境だけの問題であることが判明しました。(そして、統合テストに永遠に時間がかかるため、これは大きな問題でした。) 実稼働環境では、すべての統計を定期的に更新するジョブを実行していました。

于 2013-03-18T13:24:16.943 に答える
5

この時点で、次のことをお勧めします。


アドホック ワークロードの最適化設定を true に設定します。

EXEC sp_configure 'show advanced', 1;
GO
RECONFIGURE WITH OVERRIDE;
GO
EXEC sp_configure 'optimize for ad hoc', 1;
GO
RECONFIGURE WITH OVERRIDE
GO
EXEC sp_configure 'show advanced', 0;
GO
RECONFIGURE WITH OVERRIDE;
GO

しばらくしてもこの設定が役に立たないように思われる場合は、そのときだけ、トレース フラグの追加サポートを試してみます。これらは通常、最後の手段として予約されています。クエリ ウィンドウでグローバル フラグを使用するのではなく、SQL Server 構成マネージャーからコマンド ラインを使用してトレース フラグを設定します。http://msdn.microsoft.com/en-us/library/ms187329.aspxを参照してください。

于 2012-05-02T00:57:17.010 に答える