Есть ли способ заставить индекс остаться в памяти с SQL Server 2008?

10

У меня есть таблица с несколькими миллионами строк, из которой мне нужно время от времени выполнять некоторые запросы. Первый запрос обычно будет довольно медленным (около 10 с), а последующие запросы обычно намного быстрее (около 1 с). Через несколько часов медленный / затем быстрый цикл начинается снова.

В своем плане выполнения я проверил, что все необходимые индексы присутствуют и используются надлежащим образом, и я предполагаю, что разница в производительности связана с тем, что индекс фактически находится в памяти для последующих запросов (я прав, или есть другие возможные причины?)

Я также выполняю множество других запросов с использованием индексов, но эти запросы занимают меньше времени и их производительность менее критична, поэтому я обеспокоен тем, что эти индексы фактически выталкивают мой критический индекс из кэша памяти.

Помимо очевидного исправления «добавить больше оперативной памяти», я думал о создании сценариев для пустых запросов, которые выполняются каждый час, чтобы вернуть индекс обратно в память.

Есть ли более элегантный способ сделать это? Как способ намекнуть SQLServer, что, если у него достаточно памяти для хранения в кэше одного индекса, он должен быть таким?

Я знаю, что обычно лучше не связываться с SQLServer по поводу такого рода вещей, но необычная природа моего запроса (выполняется очень редко, но критично ко времени) заставляет меня поверить, что это будет иметь смысл (если это возможно) ,

Мне также любопытно узнать, есть ли способ узнать, какие индексы кэшируются в памяти в данный момент?

Бранн
источник

Ответы:

13

Раньше была 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/

Аарон Бертран
источник
Хм, согласно этому сценарию, таблица размером 75 МБ занимает 900 МБ пула буферов. Это нормально / возможно?
db2
1
@ db2 сколько у вас индексов?
JNK
2
Кроме того, насколько это фрагментировано ... это измерение страниц, а не данных. Ваши страницы могут быть относительно пустыми, что может привести к завышенной оценке.
Аарон Бертран
0

Попробуйте использовать KEEPPLANи KEEPPLAN FIXED запросить подсказки .

KEEPPLAN заставляет оптимизатор запросов ослабить предполагаемый порог перекомпиляции для запроса.

KEEPFIXED PLAN заставляет оптимизатор запросов не перекомпилировать запрос из-за изменений в статистике. Задание KEEPFIXED PLAN гарантирует, что запрос будет перекомпилирован только в том случае, если схема базовых таблиц изменена или если sp_recompile выполняется для этих таблиц.

StanleyJohns
источник