среда, 30 сентября 2015 г.

Способы повышения призводительности запросов SQL

Написание запросов SQL - дело непростое. Ниже представлены возможные правила и приемы которым следует следовать, если вы хотите сделать работу с SQL эффективнее и качественнее.



Избегайте множественных join в запросах.

Избегайте написания запросов с множественными Join, которые включают outer joins, cross apply, outer apply и прочие сложные подзапросы. Это снижает возможности Оптимизатора опрделять порядок выполнения и тип конструкций Join. Иногда оптимизатор вынужден использовать циклические join, несмотря на ухудшение производительности запросов изза того что очень сложно применить cross join или подзапросы.

Уберите использование курсоров в запросе.

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

Избегайте использования некоррелированных скалярных подзапросов.

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

Избегайте Multi-statement функций, возвращаемых таблицы (ФВТ)

Такие функции более затратные чем инлайновые ФВТ. SQL Server помещает инлайн ФВТ в основной запрос, подобно тому как встраиваются представления, но использует отдельный контекст и хранит результаты в промежуточной временной таблице. Отдельный контекст и рабочая таблица делают Multi-statement функции затратными в использовании.

Создание и использование Индексов

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

Понимание данных.

Понимание данных, их типов и того как запрос будет выполнятся для получения данных до принятия решения о использовании индекса. Если вы понимаете все аспекты хранения и извлечения данных, это поможет вам обрести понимание того какой столбец должен иметь кластеризованный или некластеризованный индекс. Если кластеризованный индекс используется на не уникальном столбце, то SQL Server добавит уникальный идентификатор для каждого дублирующегося ключа, а это приводит с излишним затратам. Что бы этого избежать принимайте решения правильно.

Создавайте высокоизбирательные индексы

Избирательность определяет процент строк, попадаемых под определение в таблице (отношение попадаемых строк от их количества в таблице). Если этот показатель низкий, индекс является высокоизбирательным и наиболее эффективен в использовании. Некластеризованные индексы наиболее эффективны если их показатель не выше 5%, это значит, что индекс не будет учитывать 95% строк. Если индекс возращает больше 5% строк в таблице, то скорее всего он не будет использоваться вовсе; или же другой индекс будет выбран и использован, или же вся таблица будет просканирована.

Правильно размещайте столбцы в индексе

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

Удаляйте неиспользуемые индексы

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

Создание статистики и обновлений

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

Анализируйте вашу схему определений

Последнее, но тем не менне важное – анализируйте вашу схему определений; проверяйте правильно ли используются ограничения FOREIGN KEY, NOT NULL и CHECK. Использование этих ограничений в правльном месте всегда позволяет улучшить производительность запроса, так например FOREIGN KEY позволяет упростить кнструкции join путем преобразования outer join к inner join, а CHECK – удалить неиспользуемые или избыточные предикаты.