Как повысить производительность первичных запросов в MS SQL Server?

10

У меня есть веб-сайт ASP.NET, который выполняет свое независимое кэширование данных, и данные не меняются в течение длительных периодов времени, поэтому нет необходимости запрашивать SQL Server второй раз с тем же запросом. Мне нужно улучшить производительность запросов с первого раза (девственных), которые идут к этому SQL Server. Некоторые запросы обрабатывают так много данных, что могут вызвать использование SQL Server tempdb. Я не использую переменные временных таблиц или временные таблицы, поэтому SQL Server решает использовать tempdbсам, когда это необходимо.

Мой размер базы данных составляет 16 ГБ, на моем сервере доступно 32 ГБ физической памяти.

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

Я предполагаю, что когда приходит запрос, который должен что-то хранить в базе данных tempdb, SQL Server и не хватает ОЗУ, у SQL Server есть 2 варианта:

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

2) сохранить кэшированные данные для будущих запросов и начать использовать базу данных tempdb, что приводит к записи на медленный диск.

Я не знаю, какой выбор будет делать SQL Server в этой ситуации, но мне бы хотелось, чтобы он сделал выбор № 1, потому что меня волнует только выполнение первичных (целочисленных) запросов, потому что я никогда больше не отправляю тот же запрос на SQL Server. (хотя я могу отправить аналогичный запрос).

Какова стратегия кэширования SQL Server для этого сценария?

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

Можно ли настроить SQL Server таким образом, чтобы он сделал выбор № 1? Если да, то как?

Как еще можно повысить производительность всех первичных SQL-запросов?

Поскольку я не знаю стратегии кэширования SQL Server, я хочу разместить базу данных на RAM-диске. Это обеспечит высокую скорость загрузки некэшированных данных, даже если SQL Server всегда выбирает № 1. Риск этого заключается в том, что SQL Server может начать использовать больше базы данных tempdb с меньшим объемом доступной оперативной памяти (осталось только 16 ГБ после того, как я использую 16 ГБ для ОЗУ диска), если он продолжит делать выбор № 2, что замедлит выполнение тех девственных запросов, которые вызывают разливы tempdb.

Меня интересует решение для SQL 2008 R2, но я думаю, что оно, вероятно, то же самое для SQL 2008, SQL 2005 и может быть SQL 2000.

Разъяснения:

На этом ящике не работают другие приложения, он предназначен для SQL Server . Сайт работает на отдельной коробке.

Это 64-разрядная версия SQL Server 2008 R2 Standard Edition в 64-разрядной версии Windows Server 2008 R2 Enterprise.

Я запускаю только запросы только для чтения, а база данных настроена только для чтения .

Давайте предположим, что уже есть хорошие показатели . Этот вопрос о том, как SQL Server делает выбор № 1 против выбора № 2, как он это делает, если есть способ управлять им и если RAM Disk помогает ему сделать правильный выбор для первичных запросов.

alpav
источник
Что заставляет вас думать, что tempdb используется, даже если вы не создаете временные таблицы? Используете ли вы отдельные или группировать по таблицам?
пролив Дарина
3
32/64 бит? Физический или виртуальный? Выделен ли этот сервер для SQL Server или вы также используете IIS или другие приложения на том же компьютере? Вы провели какой-либо анализ плана выполнения запроса? Можете ли вы опубликовать примеры запросов и / или планов выполнения? И еще одна удача ... следуйте руководству Кендры по ведению журнала sp_whoisactive во время выполнения вашего проблемного запроса и опубликуйте результаты.
Марк Стори-Смит
@darinstrait Наиболее вероятным объяснением будет разлив или хеширование.
Марк Стори-Смит

Ответы:

7

Ваш вопрос можно перефразировать как «Как работает запрос памяти?». Хорошее прочтение на эту тему - Понимание предоставления памяти SQL-сервером . Перед запуском запроса в исполнение может потребоваться предоставление памяти для сортировки и хэширования и других операций, требующих памяти. Это предоставление памяти является оценочным . На основании текущего состояния системы (количество запущенных и ожидающих запросов, доступной памяти и т. Д.) Система предоставляет запросу разрешение на использование памяти до требуемого количества. Как только память предоставлена, запрос начинает выполнение (возможно, ему придется подождать в страшной очереди «семафор ресурса», прежде чем он получит грант). При выполнении этого предоставление памяти гарантированопо системе. Этот объем памяти может использоваться совместно со страницами данных (поскольку они всегда могут быть записаны на диск), но никогда не может использоваться с другим использованием памяти (т. Е. Он не может быть объектом 'украсть'). Поэтому, когда запрос начинает запрашивать выделенную память из своего гранта, механизм развернет то, что вы называете «стратегией № 1»: страницы данных могут быть удалены (сброшены, если загрязнены), чтобы дать запросу память, которая была обещана. Теперь, если оценка верна и грант составляет 100% запрошенной памяти, запрос не должен «пролить». Но если оценка была неверной (сводится к оценкам количества элементов, следовательно, подлежит устаревшей статистике) или если запрос не получил весь запрашиваемый грант, запрос будет «разлит». Это когда tempdb входит в картину и производительность, как правило, танки.

Единственная ручка, которой вы располагаете, которая контролирует что-то в этом процессе, - это регулятор ресурсов . Поскольку RG может использоваться для указания параметра MIN для пула, его можно использовать для резервирования памяти для определенной рабочей нагрузки, чтобы он фактически получал запрашиваемое разрешение на использование памяти. Конечно, после того, как вы провели надлежащее расследование, которое показывает, что сокращение количества предоставленных памяти является причиной, и, конечно, после того, как было оценено влияние на другие рабочие нагрузки. И проверено, конечно.

Теперь вернемся к исходному вопросу. Если ваше расследование правильное (очень большое, если), я хотел бы указать на две проблемы:

  • вы выполняете производственные запросы, которые требуют предоставления памяти для веб-сайта . Это большой нет-нет. Предоставление памяти указывает на аналитические запросы, которым нет места в обслуживании HTTP-запросов.
  • Ваши запросы, вероятно, не являются событием, получающим запрошенную память. Опять же, даже больше нет-нет для критической рабочей нагрузки, связанной с задержкой, как веб-сайты.

Так что это говорит мне о том, что у вас есть фундаментальная проблема дизайна и архитектуры. Веб-сайты управляются задержками и должны создавать рабочую нагрузку, аналогичную OLTP, без предоставления памяти и без нагрузки на память при запросах. Не говоря уже о разливах. Аналитические запросы должны выполняться в автономных заданиях и сохранять предварительно обработанные результаты для быстрой доступности, когда их запрашивают HTTP-запросы.

Ремус Русану
источник
@Mark: большинство запросов не требуют выделения памяти. Лишь немногие операторы (особенно сортировка и хеш-соединение) нуждаются в рабочем буфере и, следовательно, запрашивают разрешение. Это стандартная «номенклатура». Возможно, вы думаете о среде выполнения и плане выполнения запроса, для которого каждый отдельный запрос требует одного и включает в себя некоторое количество памяти. Предоставление памяти намного больше (МБ). Во-вторых, посмотрите sys.dm_exec_query_memory_grants: у вас есть requested(максимум), required(минимум) и granted(фактический).
Ремус Русану
Извиняюсь. Я откуда-то обнаружил, что минимум один запрос был выделен одним и тем же клерком памяти, что было неверно.
Марк Стори-Смит
Все еще не уверен, что согласен с вашими двумя пунктами. Все виды тривиальных сортировок и операций хеширования требуют грантов на минимальном уровне, поэтому предложение о том, что они должны быть полностью исключены, кажется чрезмерным. То, что разлив для tempdb из-за недостаточных грантов - это красный флаг, безусловно, разумно, но общий запрет на любую операцию, требующую гранта, может поставить многих людей на ненужный упреждающий путь оптимизации?
Марк Стори-Смит
ОП утверждает, что имеет все необходимые показатели. Если это правда, и рабочая нагрузка имеет достаточно проблем с предоставлением памяти (и даже разливом), чтобы быть заметной, то я бы сказал, что рабочая нагрузка слишком аналитическая для веб-сайта . В конечном итоге оптимизация производительности всегда игра исследование , чтобы определить причину. Все общие заявления и запреты всегда встречаются, встречный пример, который доказывает их неправоту, это само собой разумеющееся. Есть ли у OP проблема проектирования, которая создает слишком аналитическую нагрузку? Я не знаю. Я так думаю? Я бы сказал, 87,5% уверенности да.
Ремус Русану
@Remus: Ваше предположение было хорошим, запросы моего веб-сайта на 100% аналитические. Это позволяет пользователям создавать любые возможные запросы в пользовательском интерфейсе для отправки любых возможных комбинаций фильтров, агрегатов и группировок в SQL Server (что, конечно, делает индексацию сложной). Да, я мог бы заставить их работать в асинхронном режиме, сохраняя результаты для последующего поиска, но цель состоит в том, чтобы сделать любой запрос таким быстрым, чтобы результат сразу был доступен через 2-10 секунд, а аналитические запросы - единственная функция этого веб-сайта. Я думаю, что делать их асинхронными имеет смысл, только если есть другие запросы, которые не являются аналитическими.
alpav
3

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

Вам также необходимо убедиться, что на этом же компьютере запущены другие приложения. Несмотря на то, что на устройстве установлено 32 ГБ ОЗУ, вы должны установить максимальный объем памяти на сервере базы данных, чтобы установить искусственное ограничение. Если на одном сервере запущены приложения, то SQL и другие приложения могут конкурировать за ресурсы, и имейте в виду, что SQL очень требователен к памяти.

SQL Server будет использовать базу данных tempdb для внутренней сортировки или хеш-соединений / агрегатов или операторов буферизации и т. Д., И вы не можете контролировать это поведение. Что вы можете сделать, это ограничить объем данных, возвращаемых обратно.

Вы проверили статистику ожидания на этом поле? Каждый раз, когда SQL Server ожидает ресурс, SQL Server будет отслеживать ресурс ожидания, и просмотр этой информации помогает.

Посмотрите на диагностические запросы Гленна Берри, и это станет хорошим началом для вас.

Также посмотрите на PARAMETERIZATION FORCED, как упомянуто в http://weblogs.sqlteam.com/dang/archive/2009/06/27/Forced-Parameterization-A-Turbo-Button.aspx

Санкар Редди
источник
хорошо, давайте предположим, что уже есть правильные индексы. Я забыл упомянуть, что это база данных только для чтения с запросами только для чтения, и на SQl Server не работает другое приложение.
alpav
Ваша статистика актуальна? Базы данных только для чтения не могут создавать статистику, если они отсутствуют или устарели. Ваши данные искажены или имеют уникальные значения для ключа. Есть много факторов, которые могут вызвать это поведение.
Санкар Редди
Что вы подразумеваете под «этим поведением»? Я не упоминал, что что-то идет не так. Я просто хочу повысить производительность в моих особых обстоятельствах. SQL Server оптимизирован для работы в любой ситуации, но он может или не может работать наилучшим образом в моей ситуации. Я не уверен, могу ли я доверять SQL Server, чтобы сделать сбалансированный выбор № 1 против № 2. Каждый раз, когда я добавляю новые данные, я запускаю sp_updatestats.
alpav
№1 и №2 происходят не так, как вы думаете. msdn.microsoft.com/en-us/library/ms191475(v=sql.105).aspx msdn.microsoft.com/en-us/library/aa337560(v=sql.105).aspx
Санкар Редди
2
Когда вы запускаете sp_updatestats, какое соотношение выборки вы выбрали. Коэффициент по умолчанию очень выборочный и зависит от размера индекса. Если ваши запросы запрашивают в основном (только) новые данные, и даже если вы выполняете процедуру sp_updatestats, SQL Server не может принимать правильные решения относительно планов выполнения.
Санкар Редди
2

Этот вопрос в настоящее время читается как решение проблемы. Вы решили, что решением является RAM-диск, и вы хотите, чтобы кто-то подтвердил этот выбор. Извините, не произойдет.

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

Взгляните на Buffer Management, чтобы лучше понять, как SQL Server управляет памятью, а SQL Server Memory Management объяснил некоторые основные инструменты и запросы DMV, чтобы понять, где выделена ваша память.

Как еще можно повысить производительность всех первичных SQL-запросов?

Это большая тема. Разместите запрос и план, и вы получите целевую обратную связь.

Марк Стори-Смит
источник