У нас есть мощный сервер Windows 2008 x64 (4 x 4-ядерных процессора, 32 ГБ ОЗУ) с 64-разрядной версией SQL Server 2005. У нас есть небольшая (6 ГБ), но очень важная база данных, доступ к которой несколько медленный до тех пор, пока страницы не будут кэшированы в памяти (используется очень много случайных операций ввода-вывода, поэтому шансы очень низкие, что данная страница находится в памяти, а конечные пользователи жалуются на начальную медлительность). Диски достаточно быстрые (локальный SAS 15K), но я предполагаю, что приложение написано несколько неуклюже (это решение COTS), поэтому мне интересно, есть ли способ «принудительно» сохранить базу данных в памяти в SQL Server 2005 (2008 не поддерживается поставщиком, так что нам пока не следует переходить на него), чтобы избежать начального хандры с заполнением кеша?
Мой текущий метод заключается в том, что я запускаю SELECT * из каждой таблицы в скрипте, чтобы получить страницы данных в памяти, но некоторые объекты (индексы, полнотекстовый поиск и т. Д.) Не кэшируются этим методом (и модифицируют скрипт для опроса индексов и напишите соответствующие предложения WHERE для кеширования - это комплекс кипения океана).
Нет, к сожалению, нет способа принудительно поместить базу данных в кеш. Ваш метод грубой силы, вероятно, самый простой. Вы можете приблизиться, используя скрипты дефрагментации индекса с очень низким пороговым значением, например, говоря, перестройте индекс, если он фрагментирован на 1%, например:
http://sqlserverpedia.com/wiki/Index_Main maintenance
Это займет больше времени и потребует больше операций записи на диск, но побочным эффектом будет дефрагментация индексов и обновление статистики, что в любом случае является хорошей идеей.
Хорошо - я не могу комментировать ответ Брента (пока что у меня недостаточно представителей), но если вы собираетесь пойти по маршруту дефрагментации, не обязательно перестраивать индекс - так как это создаст новые индексы, возможно увеличение базы данных, если не хватает свободного места, и гарантия того, что ваша следующая резервная копия журнала будет не меньше размера ваших индексов, и в вашем журнале может быть также тонна записей журнала (в зависимости от модели восстановления). Если вы собираетесь выполнить маршрут дефрагментации, выполните ALTER INDEX ... REORGANIZE, который не требует свободного места (ну, одна страница размером 8 КБ), но будет считывать конечный уровень в память и работать только с фрагментированными страниц. Неконцевые уровни должны поступать быстро после некоторых запросов и (в зависимости от разветвления) данных должно быть намного меньше, чем конечный уровень.
У меня было несколько сценариев обновления статистики с помощью FULLSCAN по ключевым таблицам, принудительно помещали данные в кеш и значительно ускоряли последующие DML вокруг этих таблиц. И это не было результатом устаревшей статистики, поскольку это не привело к изменению планов выполнения.
Если база данных такая маленькая, подумайте о том, чтобы разместить ее на SSD?
Почему в первую очередь удаляются объекты базы данных из кеша? Вы перезапускаете службы SQL или отключаете / отключаете базу данных? Или они вытесняются кешированием из других баз данных?
С Уважением,
СКМ.
Почему бы вам не установить второй экземпляр SQL Server только с этой базой данных и установите минимум памяти для того экземпляра на 6Гб?
Это гарантирует, что другие ваши базы данных никогда не перехватят память из вашей «маленькой, но очень важной» базы данных.
Это также будет означать, что вы можете отключить другой экземпляр, и ваша небольшая БД останется в памяти.
Я бы использовал профилировщик для проверки вашего sql. Сравните «логические» чтения с «физическими». SQL-сервер умен и будет использовать необходимую ему оперативную память для наиболее эффективных результатов.
Также убедитесь, что ваша автоматическая статистика обновлена.
Без более подробного представления о типе запроса и размерах таблиц db это звучит немного странно.