数百万行のテーブルがあり、そこからクエリを時々実行する必要があります。通常、最初のクエリはかなり遅く(約10秒)、その後のクエリは通常はかなり高速です(約1秒)。数時間後、低速/高速のサイクルが再び始まります。
必要なすべてのインデックスが存在し、適切に使用されていることを実行プランで確認しました。パフォーマンスの違いは、インデックスが後続のクエリのために実際にメモリ内にあるためであると思います(私は正しいですか、それとも他にもあります)考えられる原因?)
また、インデックスを使用して他の多くのクエリも実行していますが、これらのクエリは時間がかかりませんし、そのパフォーマンスはそれほど重要ではないため、これらのインデックスが実際に重要なインデックスをメモリキャッシュから押し出しているのではないかと心配しています。
明らかな「RAMを追加する」修正とは別に、インデックスをメモリに強制的に戻すためにダミークエリを1時間ごとに実行するスクリプトを作成することを考えてきました。
これを行うためのよりエレガントな方法はありますか? SQLServerに、1つの単一のインデックスをキャッシュに保持するのに十分なメモリしかない場合は、それをキャッシュする必要があることを示唆する方法と同じように
私は通常、そのようなことに関してSQLServerを台無しにするのが最善ではないことを知っていますが、私のクエリの異常な性質(非常にまれに実行されますが、タイムクリティカル)は、それが理にかなっていると信じています(可能な場合) 。
また、特定の時点でメモリにキャッシュされているインデックスを確認する方法があるかどうかも知りたいです。
以前は DBCC PINTABLE
コマンドですが、6.5または7.0で動作しなくなったと思います。ステートメントはおそらくまだそれを試した場合に機能したことを示唆しますが、それだけで戻り、実際には何も行われません。
残念ながら、キャッシュに保持されるインデックスを制御する方法は実際にはありません-定期的にホットなテーブルについて私が知っている最善の回避策は、手動でホットに保つことです(これは既に質問で説明しています)。
どのインデックスがメモリにあるかについては、 sys.sm_os_buffer_descriptors
。これに関するヒントを公開しました:
http://www.mssqltips.com/sqlservertip/2393/determine-sql-server-memory-use-by-database-and-object/
KEEPPLAN
およびKEEPPLAN FIXED
query hints を使用してみてください。
KEEPPLANにより、クエリオプティマイザーはクエリの推定再コンパイルしきい値を緩和します。
KEEPFIXED PLANは、統計の変更が原因でクエリオプティマイザーがクエリを再コンパイルしないように強制します。 KEEPFIXED PLANを指定すると、基になるテーブルのスキーマが変更された場合、またはこれらのテーブルに対してsp_recompileが実行された場合にのみ、クエリが確実に再コンパイルされます。