SQL Server 2012に各テナントの行がtenant_id
列(別名Shared Database, Shared Schemaという方法)で識別されるマルチテナントデータベースがあります。一部のテナント、特に新しいテナントでは行がほとんどなく、他のテナントでは行がほとんどありません。マルチテナントSQL Serverデータベースとパラメータスニッフィング
SQL Serverのクエリオプティマイザは、通常、最初の実行中に提供されたパラメータに基づいてクエリプランを作成し、別のパラメータが提供されていても将来のすべてのクエリに対してこのプランを再利用します。これはparameter sniffingとして知られています。
データベースで問題が発生するのは、小さなテナントを指すパラメータに基づいてSQL Serverがこれらのプランを構築することがあります。テナントは問題なく動作しますが、キャッシュされたプランを大きなテナントに再適用すると、壊滅的に(通常は実際にタイムアウトする)。通常は、大規模なテナントのうちの1人がタイムアウトエラーの発生について私たちに連絡した場合にのみ、システムに入り、すべてのクエリプランを手動でフラッシュして修正する必要があります。
SQL Serverがクエリプラン()をキャッシュしないようにするために使用できるクエリヒントがありますが、クエリが呼び出されるたびにクエリプランが再生成されるため、余分なオーバーヘッドが発生します。もう1つの問題は、クエリでOPTIMIZE FOR UNKNOWN
ヒントを指定できないEntity Frameworkを使用していることです。
したがって、パラメータスニッフィングに関してマルチテナントデータベースのベストプラクティスは何ですか?すべてのクエリでパラメータスニッフィングを指定しなくても、データベース全体でパラメータスニッフィングを無効にする方法はありますか?もしそうなら、それは最善のアプローチですか?他の方法でデータを分割する必要がありますか?私が考えていない他のアプローチがありますか?
AFAIK、これを修正するには、ストアドプロシージャを使用する必要があります。あなたの周りにあなたを得ることができるEFのいくつかの機能がない限り。 – RBarryYoung
'OPTIMIZE FOR UNKNOWN'には、あなたが記述する動作はありません。あなたは 'OPTION(RECOMPILE) 'と混同しています。エンタープライズ版を使用している場合は、計画ガイドを参照してヒントを提供できます。または、トレースフラグ(4136)が[パラメータスニッフィングを完全に無効にする](http://support.microsoft.com/kb/980653)ですが、**インスタンス**データベースには適用されません。 –