Сообщение администратору
Имя:
Почта:
Сообщение:
Вход на сайт
Логин:
Пароль:

Поддержка  •  Дневник  •  О сайте  •  Реклама  •  Поставить баннер  •  Прислать  •  Хроника  •  Translate  •  Рекомендованное  •  Написать администратору Гости: 6    Участники: 0 Авторизация Авторизация   Регистрация 
Метод Научного Тыка
RULVEN
Поиск  
Blackball iMag | интернет-журнал
RSS-лента
Поделиться ссылкой:
Каталог


Начало » Разработка ПО » Microsoft SQL Server » Оптимизация запросов

Оптимизация запросов


Добавлено: Пн 27.12.2010 • Sergeant
Источник: источник
Просмотров: 1167
Комментарии: 0


При использовании команды UNION учтите, что на всем возвращаемом наборе по умолчанию выполняется эквивалент команды SELECT DISTINCT. Иначе говоря - проверяется наличие повторяемых строк. Если вы уверены, что дублирующих записей в результате вашего запроса не будет, то используйте конструкцию UNION ALL. Этот вариант запроса не проверяет наличие дублирующих строк и работает намного быстрее, чем обычный UNION.

Рассмотрим пример, когда вам надо объединить результат двух или более запросов, используя UNION:
SELECT column_name1, column_name2
FROM table_name1
WHERE column_name1 = some_value
UNION
SELECT column_name1, column_name2
FROM table_name1
WHERE column_name2 = some_value
Тот же самый запрос можно переписать, значительно увеличив производительность:
SELECT DISTINCT column_name1, column_name2
FROM table_name1
WHERE column_name1 = some_value OR column_name2 = some_value
Если вы уверены, что повторяющихся строк в результирующем наборе данных нет, то можно еще больше увеличить эффективность запроса - уберите конструкцию DISTINCT.

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

Может быть вы слышали о команде SET ROWCOUNT. Как и оператор TOP он предназначен для ограничения количества строк в возвращаемом наборе. На самом деле SET ROWCOUNT и TOP выполняют одну и ту же функцию. Однако есть отдельные случаи (например, записи, возвращаемые из несортированной кучи) где оператор TOP более эффективен, чем использование SET ROWCOUNT. Поэтому предпочтительно применять TOP для ограничения количества записей в запросе.

В конструкции WHERE различные используемые операторы непосредственно влияют на скорость выполнения запроса. Это происходит из-за того, что некоторые операторы срабатывают быстрее других. Конечно, не всегда удается изменить эту часть запроса, но иногда это можно сделать. Вот основные операторы применяемые в конструкциях WHERE, отсортированные по производительности в сторону уменьшения:
1. =
2. >, >=, <, <=
3. LIKE
4. <>
Применяйте = где только возможно, и как можно реже следует использовать <>.

Не используйте код, который ничего не делает. Это может звучать странно, однако некоторые разработчики пишут подобные конструкции:
SELECT column_name FROM table_name
WHERE 1 = 0
После выполнения такого запроса не будет возвращено ни одной строки. Очевидно это простой пример, существуют запросы намного длиннее и запутаннее как этот, которые ничего полезного не выполняют и не должны исполнятся. Они просто тратят впустую ресурсы сервера.

Многие разработчики периодически используют в конструкции WHERE следующее сравнение строк:
SELECT column_name FROM table_name
WHERE LOWER(column_name) = 'name'
Другими словами, эти разработчики полагают, что данные на SQL сервере чувствительны к регистру, хотя обычно это не так. Если ваш сервер настроен не чувствительным к регистру (case-sensitive), то вам не надо использовать команды LOWER или UPPER для выполнения сравнения строк. Просто не используйте эти функции. Это увеличит скорость выполнения запроса, так как использование любых текстовых функций в конструкции WHERE приводит к снижению призводительности.
А что если ваша база настроена чувствительной к регистру? Нужно ли в таком случае использовать функции LOWER и UPPER для сравнения строк? Нет. Приведенный далее пример по-прежнему обходится без их применения:
SELECT column_name FROM table_name
WHERE column_name = 'NAME' or column_name = 'name'
Если использовать такую технику, вместе с соответствующими индексами, то подобный запрос будет выполняться намного быстрее, чем в первом примере.

Запросы, использующие конструкцию NOT IN, обладают низкой эффективностью, потому что оптимизатору запросов SQL Server приходится производить сканирование вложенных таблиц. Использование любого из следующих советов может значительно повысить скорость выполнения:
· Использование EXISTS или NOT EXISTS
· Использование IN
· Выполнение LEFT OUTER JOIN и проверка на NULL соответствующего столбца

Не бойтесь свободно использовать однострочные или блоки комментариев в вашем коде. Это ни коим образом не отразится на эффективности запросов.

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

Если вы выбираете что использовать - ограничение или триггер для решения одной и той же задачи, то всегда выбирайте ограничение. Аналогично для ситуаций: ограничение и правило, или ограничение и значение по умолчанию. Ограничение требует намного меньше ресурсов, чем триггеры, правила или значения по умолчанию.

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

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

Для создания первичного ключа многие разработчики используют или поле identity (с целочисленным типом данных), или глобально уникальный идентификатор (поле с типом данных uniqueidentifier). Если ваше приложение может работать и с тем, и с другим типом данных, лучше использовать identity. Дело в том, что это поле имеет размер до 4 байт, в то время как uniqueidentifier - 16 байт. Используя целочисленное поле можно создать меньший по размеру и быстрый индекс.

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

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

Избегайте вложенных представлений (VIEW) - когда одно представление внутри себя ссылается на другое. Хоть это и не запрещено, в данном случае становится сложнее понять и найти источник проблем с производительностью ваших запросов. Лучше создавать отдельные представления, чем вложенные.

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

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



Мне нравится 0   Мне не нравится 0



Комментарии

Чтобы добавить видео с YouTube, нужно написать [@youtube=xxxxx] , где xxxxx – ID видео.


Комментарии: 0
Нет ни одного комментария.
Разработано на основе BlackNight CMS
Release v.2024-11-16
© 2000–2024 Blackball
Дизайн & программирование:
О сайтеРеклама
Visitors
Web-site performed by Sergey Drozdov
BlackballРекламаСтатистикаПоддержка
МузыкаПлейлистыКиноВидеоИгрыАудиоПрограммыСтатьиКартинкиЮморФорумДневник сайтаПрислать контентРекомендованное