I have a multi-tenant database in SQL Server 2012 where each tenant's rows are identified by a tenant_id
column (aka the Shared Database, Shared Schema approach). Some tenants, particularly the newer ones, have very few rows, while others have many.
SQL Server's query optimizer normally builds a query plan based on the parameters provided during its first execution, then re-uses this plan for all future queries even if different parameters are provided. This is known as parameter sniffing.
データベースの問題は、SQL Server が小さなテナントを指すパラメーターに基づいてこれらのプランを構築することがあり、そのテナントでは問題なく機能しますが、キャッシュされたプランを大きなテナントに再適用すると壊滅的に失敗することです (通常はタイミング実際、アウト)。通常、この状況は、大規模なテナントの 1 つからタイムアウト エラーの発生について問い合わせがあった場合にのみわかります。その後、システムに入り、すべてのクエリ プランを手動でフラッシュして修正する必要があります。
SQL Server がクエリ プランをキャッシュしないようにするために使用できるクエリ ヒントがあります ( OPTIMIZE FOR UNKNOWN
) が、クエリが呼び出されるたびにクエリ プランが再生成されるため、追加のオーバーヘッドが発生します。追加の問題は、OPTIMIZE FOR UNKNOWN
クエリでヒントを指定する機能を提供しない Entity Framework を使用していることです。
問題は、パラメータ スニッフィングに関するマルチテナント データベースのベスト プラクティスは何かということです。すべてのクエリで指定することなく、データベース全体でパラメーター スニッフィングを無効にする方法はありますか? もしそうなら、それは最善のアプローチですか?他の方法でデータを分割する必要がありますか? 私が考えていない他のアプローチはありますか?