Воспламенение или нагревающийся кэш в SQL Server

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

CHECKPOINT
GO
DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO
EXEC sp_MyProc 12345

На Сохраненном proc я работал сегодня, я заметил, что, когда я выполнил его с этими строками, потребовалось приблизительно 18 минут каждый раз. Когда я уехал, эти строки от него только взяли 3. Наблюдение решительного различия, вызванного при наличии очищенного кэша по сравнению с запущенным кэшем, который я решил добавить следующее, чтобы видеть, мог ли я вручную главный кэш прежде, чем выполнить мой proc и видеть то, что это сделало к производительности.

CHECKPOINT
GO
DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO
SELECT top 1 '1' from Table1
EXEC sp_MyProc 12345

Поскольку Вы, возможно, предположили sp_MyProc использование Table1 вполне немного. Я был удивлен найти, что выполнение этого удаляло мое время выполнения приблизительно к 6 минутам последовательно. Хотя это действительно улучшает производительность, это смотрит немного hackish, и мне любопытно, существует ли что-то встроенное в SQL Server, который выполнит это.

  • Делает это для улучшения производительности неслыханных запросов?
  • Я даже прав предположить, что улучшение вовремя, что я видел, было результатом "Запущенного" кэша?

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

ОБНОВЛЕНИЕ: Хорошо я смущен, чтобы сказать, что я пытался воспроизвести это поведение сегодня, но не мог. Я говорил с некоторыми людьми на своей работе, и она похожа на часть материала, который они делали на DB, вчера, возможно, заставил его появиться, как будто мой выбор перед proc улучшал производительность, когда на самом деле это не было. Мне все еще было бы интересно слышать, знает ли кто-либо, возможно ли "воспламенение" кэш через.

9
задан Abe Miessler 4 February 2010 в 12:59
поделиться

2 ответа

Предоставление «ответа», чтобы попытаться проработать это, поскольку это то, что меня особенно интересует.

Я наткнулся на эта статья MSDN о том, как узнать, что находится в кэше SQL Server. Там есть запрос, который покажет вам, сколько страниц данных кэшировано по объектам - я изменил его, чтобы имя индекса, как показано ниже:

SELECT count(*) AS cached_pages_count, obj.name, index_id, i.name AS IndexName
FROM sys.dm_os_buffer_descriptors AS bd 
    INNER JOIN 
    (
        SELECT object_id, object_name(object_id) AS name 
            ,index_id ,allocation_unit_id
        FROM sys.allocation_units AS au
            INNER JOIN sys.partitions AS p 
                ON au.container_id = p.hobt_id 
                    AND (au.type = 1 OR au.type = 3)
        UNION ALL
        SELECT object_id, object_name(object_id) AS name   
            ,index_id, allocation_unit_id
        FROM sys.allocation_units AS au
            INNER JOIN sys.partitions AS p 
                ON au.container_id = p.partition_id 
                    AND au.type = 2
    ) AS obj 
        ON bd.allocation_unit_id = obj.allocation_unit_id
    LEFT JOIN sysindexes i ON obj.object_id = i.id AND obj.index_id = i.indid
WHERE database_id = db_id()
GROUP BY obj.name, index_id, i.name
ORDER BY cached_pages_count DESC;

Если вы попробуете выполнить следующие шаги, вы сможете увидеть, что происходит в отношении кеширования. Сделайте это в своей базе данных (в отличие от, например,master):

1) контрольная точка + очистка кеша
2) запустите вышеуказанный запрос, и вы, вероятно, должны получить 1 возвращенную запись (для sysobjvalues), но ничего для Table1
{ {1}} 3) теперь запустите оператор SELECT TOP 1 '1' FROM MyTable
4) повторно запустите вышеуказанный запрос и посмотрите, что теперь появляется в результатах - вы вероятно, вы увидите запись (и) для MyTable, показывающую кэшированные страницы - запишите это число

. Это должно дать вам представление об уровне кэширования данных, который происходит для этого начального SELECT. Если вы повторите этот процесс еще раз, но вместо оператора SELECT TOP выполните свой sproc, а затем посмотрите, сколько заканчивается в кеше при его запуске - возможно, сравнение этих результатов покажет относительный объем кэширования, выполняемого SELECT TOP 1 по сравнению с вызовом sproc - и это относительное количество может указывать на улучшение производительности.

Это очень похоже на «размышления вслух». Я бы не подумал, что ТОП 1 действительно значительно загрузил бы кеш для вызова sproc, но именно поэтому меня интересует этот вопрос!

Сначала я подумал, что это больше связано с другими факторами (например, с нагрузкой на сервер / диск). Вы можете поочередно переключаться между двумя сценариями для 3 или 4 итераций, один за другим, чтобы дважды проверить, действительно ли подход SELECT TOP постоянно лучше (помогите минимизировать риск того, что это будет разовая ошибка)

Надежда это помогает / запускает мяч.

Обновление:
Теперь вы знаете, что не SELECT TOP заполняет кеш, хороший способ заполнить кеш, как сказал AdrianBanks.По крайней мере, теперь вы можете объяснить, что было неожиданным / сбивающим с толку разницей в производительности! Сохраните приведенный выше сценарий в своей библиотеке, он полезен для проверки состояния кеша.

3
ответ дан 3 November 2019 в 07:13
поделиться

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

Насколько я понимаю, SQL Server загружает страницы данных (содержащие данные таблицы или данные индекса) в память по мере необходимости при выполнении запросов. Они хранятся в памяти, если они не очищены явным образом (с помощью DBCC DROPCLEANBUFFERS - т. Е. Удаляются все буферы (кэшированные страницы) в памяти, которые не были изменены с момента загрузки), либо есть нехватка памяти (либо низкий уровень свободной память на машине или максимальный объем памяти, установленный на SQL Server). Из-за такого поведения может быть полезно разогреть базу данных SQL Server для использования. При последующем запуске запроса данные, необходимые для сбора результатов запроса, могут уже находиться в памяти. Если это так, запрос будет выполняться быстрее, так как он потребует меньше операций ввода-вывода.

Проблема, однако, заключается в том, чтобы знать, что предварительно кэшировать и, следовательно, какие запросы выполнять. Вы можете запустить SQL-трассировку для типичной активности, а затем воспроизвести ее для предварительного кеширования часто используемых данных. Однако, не позволяя SQL Server удерживать огромный объем выделенной памяти, вам всегда придется читать некоторые вещи с диска (если у вас нет небольшой базы данных). Поскольку вы никогда не узнаете, что кэшируется, а что нет, полагаться на это поведение для повышения производительности кажется неправильным.

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

2
ответ дан 3 November 2019 в 07:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: