Когда у вас есть запрос или хранимая процедура, требующие настройки производительности, что вы делаете в первую очередь?
sql
sql-server
database
performance
Terrapin
источник
источник
Ответы:
Вот удобный список вещей, которые я всегда даю тем, кто спрашивает меня об оптимизации.
В основном мы используем Sybase, но большинство советов применимы ко всем.
SQL Server, например, поставляется с множеством инструментов для мониторинга / настройки производительности, но если у вас нет ничего подобного (а может быть, даже если есть), я бы подумал о следующем ...
99% проблем, которые я видел, вызваны объединением слишком большого количества таблиц . Чтобы исправить это, нужно выполнить половину соединения (с некоторыми таблицами) и кэшировать результаты во временной таблице. Затем выполните остальную часть запроса, присоединившись к этой временной таблице.
Контрольный список оптимизации запросов
#temp
таблицы могут работать намного лучше, чем@table
переменные с большими объемами (тысячи строк).источник
источник
Немного не по теме, но если вы контролируете эти вопросы ...
Высокий уровень и большое влияние.
источник
CREATE INDEX
Убедитесь, что для ваших предложений
WHERE
и есть индексыJOIN
. Это значительно ускорит доступ к данным.Если ваша среда представляет собой витрину или хранилище данных, индексов должно хватить почти для любого мыслимого запроса.
В транзакционной среде количество индексов должно быть меньше, а их определения - более стратегическими, чтобы обслуживание индексов не перетягивало ресурсы. (Техническое обслуживание Индекса , когда листы индекса должны быть изменены , чтобы отразить изменения в базовой таблице, как и с
INSERT, UPDATE,
иDELETE
операциями.)Кроме того, помните о порядке полей в индексе - чем более избирательно (с большей мощностью) поле, тем раньше в индексе оно должно появиться. Например, вы запрашиваете подержанные автомобили:
Цена обычно имеет более высокую мощность. В наличии может быть всего несколько десятков цветов, но вполне возможно, что запрашиваемые цены будут тысячи.
Из этих вариантов индекса
idx01
обеспечивает более быстрый путь для удовлетворения запроса:Это связано с тем, что меньшее количество автомобилей будет соответствовать цене, чем выбор цвета, что дает механизму запросов гораздо меньше данных для анализа.
Известно, что у меня есть два очень похожих индекса, различающихся только порядком полей для ускорения запросов (имя, фамилия) в одном и (фамилия, имя) в другом.
источник
Недавно я усвоил трюк: SQL Server может обновлять локальные переменные, а также поля в операторе обновления.
Или более читабельная версия:
Я использовал это для замены сложных курсоров / объединений при выполнении рекурсивных вычислений, а также значительно повысил производительность.
Вот подробности и пример кода, который позволил добиться фантастических улучшений в производительности: http://geekswithblogs.net/Rhames/archive/2008/10/28/calculating-running-totals-in-sql-server-2005---the-optimal. ASPX
источник
Предполагая, что здесь MySQL, используйте EXPLAIN, чтобы узнать, что происходит с запросом, убедитесь, что индексы используются максимально эффективно, и попытайтесь исключить сортировку файлов. Высокая производительность MySQL: оптимизация, резервное копирование, репликация и многое другое - отличная книга по этой теме, как и блог о производительности MySQL .
источник
@Terrapin есть еще несколько различий между isnull и coalesce, которые стоит упомянуть (помимо соответствия ANSI, что для меня очень важно).
Coalesce против IsNull
источник
Иногда в SQL Server, если вы используете OR в предложении where, это действительно снижает производительность. Вместо использования ИЛИ просто сделайте два выбора и объедините их вместе. Вы получаете те же результаты на 1000-кратной скорости.
источник
Посмотрите на предложение where - проверьте использование индексов / убедитесь, что ничего глупого не делается
источник
Обычно я начинаю с объединений - я выбиваю каждое из них из запроса по одному и повторно запускаю запрос, чтобы понять, есть ли конкретное соединение, с которым у меня проблемы.
источник
Во все мои временные таблицы я люблю добавлять уникальные ограничения (где это необходимо) для создания индексов и первичные ключи (почти всегда).
источник
Я взял за привычку всегда использовать переменные связывания. Возможно, переменные связывания не помогут, если СУБД не кэширует операторы SQL. Но если вы не используете переменные связывания, у РСУБД нет возможности повторно использовать планы выполнения запросов и проанализированные операторы SQL. Экономия может быть огромной: http://www.akadia.com/services/ora_bind_variables.html . Я работаю в основном с Oracle, но Microsoft SQL Server работает почти так же.
По моему опыту, если вы не знаете, используете ли вы переменные связывания, скорее всего, нет. Если ваш язык приложения не поддерживает их, найдите тот, который поддерживает. Иногда вы можете исправить запрос A, используя переменные связывания для запроса B.
После этого я разговариваю с нашим администратором баз данных, чтобы выяснить, что причиняет РСУБД наибольшую боль. Обратите внимание, что вы не должны спрашивать «Почему этот запрос медленный?» Это все равно, что попросить врача удалить вам аппендикс. Конечно, проблема может быть в вашем запросе, но так же вероятно, что что-то еще не так. Как разработчики, мы склонны мыслить строчками кода. Если линия медленная, исправьте эту линию. Но СУБД - это действительно сложная система, и ваш медленный запрос может быть признаком гораздо более серьезной проблемы.
Слишком много советов по настройке SQL - кумиры культа карго. В большинстве случаев проблема не связана или минимально связана с используемым синтаксисом, поэтому обычно лучше использовать максимально чистый синтаксис. Затем вы можете начать искать способы настройки базы данных (а не запроса). Изменяйте синтаксис только тогда, когда это не удается.
Как и при любой настройке производительности, всегда собирайте значимую статистику. Не используйте время настенных часов, если это не настраивается пользователем. Вместо этого посмотрите на такие вещи, как время ЦП, извлеченные строки и блоки, считанные с диска. Слишком часто люди оптимизируются не для того.
источник
Первый шаг: посмотрите на план выполнения запроса!
TableScan -> плохой
NestedLoop -> предупреждение
Meh TableScan за NestedLoop -> DOOM!
УСТАНОВИТЬ СТАТИСТИКУ IO ВКЛ
УСТАНОВИТЬ ВРЕМЯ СТАТИСТИКИ ВКЛ
источник
Выполнение запроса с использованием WITH (NoLock) для меня в значительной степени является стандартной операцией. Любой, кто поймал выполнение запросов к таблицам размером в десятки гигабайт, без этого вынимается и расстреливается.
источник
Преобразуйте запросы NOT IN в LEFT OUTER JOINS, если это возможно. Например, если вы хотите найти все строки в Table1, которые не используются внешним ключом в Table2, вы можете сделать это:
Но вы получите гораздо лучшую производительность с этим:
источник
@ DavidM
В SQL Server план выполнения дает вам то же самое - он сообщает вам, какие индексы используются и т. Д.
источник
Индексируйте таблицы по критериям, которые вы фильтруете
источник
Не обязательно трюк с производительностью SQL как таковой, но определенно связанный:
Хорошей идеей было бы использовать memcached там, где это возможно, поскольку это было бы намного быстрее, просто извлекая предварительно скомпилированные данные непосредственно из памяти, а не из базы данных. Также есть разновидность MySQL, в которую встроен memcached (сторонний).
источник
Убедитесь, что длина вашего индекса как можно меньше. Это позволяет БД читать больше ключей из файловой системы за раз, тем самым ускоряя ваши соединения. Я предполагаю, что это работает со всеми БД, но я знаю, что это конкретная рекомендация для MySQL.
источник
Я ищу:
источник
Обычно первая строка внутри моих хранимых процедур, если мне действительно не нужно использовать
@@ROWCOUNT
.источник
В SQL Server используйте директиву nolock. Это позволяет команде select завершиться без ожидания - обычно заканчиваются другие транзакции.
источник
Удалите курсоры везде, где они не нужны.
источник
Удалите вызовы функций в Sprocs, где многие строки будут вызывать функцию.
Мой коллега использовал вызовы функций (например, получение lastlogindate из идентификатора пользователя) для возврата очень широких наборов записей.
Для оптимизации я заменил вызовы функций в sproc на код функции: у меня время работы многих sproc уменьшилось с> 20 секунд до <1.
источник
источник
Я люблю использовать
Над
Когда мне не нужна поддержка нескольких аргументов, которую дает вам coalesce.
http://blog.falafel.com/2006/04/05/SQLServerArcanaISNULLVsCOALESCE.aspx
источник
Не ставьте перед именами хранимых процедур префикс sp_, потому что все системные процедуры начинаются с sp_, и SQL Server будет труднее искать вашу процедуру при ее вызове.
источник
Грязные чтения -
Предотвращает мертвые блокировки, когда целостность транзакции не является абсолютно необходимой (что обычно верно)
источник
Я всегда сначала использую SQL Profiler (если это хранимая процедура с большим количеством уровней вложенности) или планировщик выполнения запросов (если это несколько операторов SQL без вложенности). В 90% случаев вы можете сразу найти проблему с помощью одного из этих двух инструментов.
источник