Вопрос кеша SQL Server - PullRequest
       12

Вопрос кеша SQL Server

10 голосов
/ 05 января 2010

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

Ответы [ 5 ]

9 голосов
/ 05 января 2010

Когда вы выполняете запрос, данные считываются в память блоками. Эти блоки остаются в памяти, но они стареют. Это означает, что блоки помечены с последним доступом, и когда Sql Server требует еще один блок для нового запроса и кэш-память заполнена, наименее использованный блок (самый старый) удаляется из памяти. (В большинстве случаев - блоки сканирования полных таблиц мгновенно стареют, чтобы предотвратить полное сканирование таблиц, переполнение памяти и перегрузка сервера).

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

Итак, что на самом деле задает ваш вопрос: «Могу ли я получить нужные блоки данных в память, не считывая их в память (фактически выполняя запрос)?». Ответ отрицательный, если только вы не хотите кэшировать целые таблицы и постоянно размещать их в памяти, что, исходя из времени запроса (и, следовательно, размера данных), который вы описываете, вероятно, не является хорошей идеей.

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

  • создание индекса, в котором запрос мог бы использовать индекс, чтобы избежать неэффективных запросов и полного сканирования таблицы
  • добавление дополнительных столбцов к индексу, чтобы избежать повторного чтения с диска. Например, у вас есть запрос, который возвращает столбцы A и B с предложением where для A и C, и у вас есть индекс для столбца A. Ваш запрос будет использовать индекс для столбца A, для которого требуется одно чтение с диска, но затем потребуется второй диск нажмите, чтобы получить столбцы B и C. Если в индексе есть все столбцы A, B и C, можно избежать второго обращения к диску для получения данных.
3 голосов
/ 05 января 2010

Не думаю, что генерация плана выполнения будет стоить больше 1 секунды.

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

Данные в кэше могут быть повторно использованы любым дальнейшим запросом (хранимая процедура или простой выбор).

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

2 голосов
/ 05 января 2010

Вы можете проверить план выполнения, чтобы узнать, какие таблицы и индексы использует ваш запрос. Затем вы можете выполнить SQL, чтобы получить данные в кэш, в зависимости от того, что вы видите.

  • Если вы видите поиск в кластеризованном индексе, вы можете просто сделать SELECT * FROM my_big_table, чтобы заставить все страницы данных таблицы в кеш.
  • Если вы видите некластеризованный поиск по индексу, вы можете попробовать SELECT first_column_in_index FROM my_big_table.

Для принудительной загрузки определенного индекса вы также можете использовать табличную подсказку WITH(INDEX(index)) в запросах на разогрев кеша.

0 голосов
/ 10 февраля 2016

Данные кеша SQL сервера читаются с диска. Последовательные чтения сделают меньше IO. Это очень помогает, поскольку дисковый ввод-вывод обычно является узким местом.

Больше на: http://blog.sqlauthority.com/2014/03/18/sql-server-performance-do-it-yourself-caching-with-memcached-vs-automated-caching-with-safepeak/

0 голосов
/ 05 января 2010

План выполнения (кэшированная информация для вашей процедуры) используется повторно каждый раз, даже с различными параметрами. Это одно из преимуществ использования хранимых процедур.

При первом запуске хранимой процедуры SQL Server генерирует план выполнения и помещает его в кэш процедур.

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

Планы выполнения удаляются из кэша процедур на основании их "возраста". (из MSDN: объекты, на которые редко ссылаются, вскоре могут быть освобождены, но фактически не освобождаются, если только для других объектов не требуется память.)

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

Более подробная информация доступна в документации MSDN: http://msdn.microsoft.com/en-us/library/ms181055(SQL.90).aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...