[Закрываются] любимые настраивающие приемы производительности

df = pd.DataFrame({'A': 'foo bar foo bar foo bar foo foo'.split(),
                   'B': 'one one two three two two one three'.split(),
                   'C': np.arange(8), 'D': np.arange(8) * 2})
df[df['A']=='foo']

OUTPUT:
   A      B  C   D
0  foo    one  0   0
2  foo    two  2   4
4  foo    two  4   8
6  foo    one  6  12
7  foo  three  7  14
126
задан 3 revs, 3 users 100% 27 August 2014 в 11:44
поделиться

29 ответов

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

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

99% проблем , который я видел, вызываются путем помещения слишком много таблиц в соединении . Фиксация для этого должна сделать половину соединения (с некоторыми таблицами) и кэшировать результаты во временной таблице. Затем сделайте остальную часть запроса, присоединяющегося на той временной таблице.

Контрольный список Оптимизации запросов

  • Выполнение UPDATE STATISTICS на базовых таблицах
    • Много систем выполняют это, поскольку запланированное еженедельное задание
  • Удаляет записи из базовых таблиц (возможно архивируют удаленные записи)
    • , Рассматривают выполнение этого автоматически один раз в день или один раз в неделю.
  • Восстанавливают Индексы
  • , Восстанавливают Таблицы (данные BCP/в)
  • Дамп / Перезагрузка база данных (решительный, но мог бы зафиксировать повреждение)
  • Сборка новое, более соответствующее индексное
  • Выполнение DBCC, чтобы видеть, существует ли возможное повреждение в базе данных
  • Блокировки / Мертвые блокировки
    • Не Гарантируют никакие другие процессы, работающие в базе данных <ул.> <литий> Особенно, DBCC
    • Являются Вами использующий строку или блокировку уровня страницы?
    • Блокировка таблицы исключительно прежде, чем запустить запрос
    • Проверка, что все процессы получают доступ к таблицам в том же порядке
  • , Является индексами, используемыми соответственно?
    • Joins будет только использовать индекс, если оба выражения будут точно совпадающим типом данных
    • , то Индекс будет только использоваться, если первое поле (поля) на индексе будет подобрано в запросе
    • , кластеризируемые индексы, используемые в соответствующих случаях? <ул.> <литий> данные диапазона <литий>, ГДЕ поле между value1 и value2
  • Маленький Joins Хороший Joins
    • По умолчанию оптимизатор, только рассмотрит таблицы 4 за один раз.
    • Это означает, что в соединениях больше чем с 4 таблицами, имеет хороший шанс выбора неоптимального плана запросов
  • , Разбивают Соединение
    • , можно ли разбить соединение?
    • Предызбранные внешние ключи во временную таблицу
    • Делают половину соединения и помещают результаты во временную таблицу
  • , Вы использующий правильный вид временной таблицы?
    • #temp таблицы могут работать намного лучше, чем @table переменные с большими объемами (тысячи строк).
  • Поддерживают Сводные таблицы
    • , Сборка с включает базовые таблицы
    • Сборка ежедневно / каждый час / и т.д.
    • Сборка для данного случая
    • , Сборка инкрементно или разрушение / восстанавливают
  • , Видят то, что план запросов с ПЛАНОМ ВЫПОЛНЕНИЯ НАБОРА НА [1 139]
  • , См. what’s, на самом деле происходящий со СТАТИСТИКОЙ НАБОРА IO НА [1 140]
  • Сила индекс с помощью прагмы: (индекс: myindex)
  • Сила использование порядка таблицы УСТАНОВИЛО FORCEPLAN НА [1 142]
  • Сниффинг Параметра:
    • Хранимая процедура Повреждения в 2
    • вызов proc2 от proc1
    • позволяет оптимизатору выбирать индекс в proc2, если @parameter был изменен proc1
  • , можно ли улучшить аппаратные средства?
  • , Во сколько Вы работаете? Существует ли более тихое время?
  • Сервер репликации (или другой безостановочный процесс) выполнение? Можно ли приостановить его? Выполнять его, например, каждый час?
114
ответ дан 24 November 2019 в 00:53
поделиться

Я всегда перехожу к SQL Profiler (если это - хранимая процедура с большим количеством уровней вложенности), или планировщик выполнения запросов (если это - несколько SQL-операторов без вложения), сначала. 90% времени можно сразу найти проблему с одним из этих двух инструментов.

0
ответ дан 24 November 2019 в 00:53
поделиться

Мне нравится использовать

isnull(SomeColThatMayBeNull, '')

более чем

coalesce(SomeColThatMayBeNull, '')

, Когда мне не нужны несколько поддержка аргумента, которые объединяют, дает Вам.

http://blog.falafel.com/2006/04/05/SQLServerArcanaISNULLVsCOALESCE.aspx

0
ответ дан 24 November 2019 в 00:53
поделиться

Грязные чтения -

set transaction isolation level read uncommitted

Предотвращают тупики, где целостность транзакций не абсолютно необходима (который обычно верен)

0
ответ дан 24 November 2019 в 00:53
поделиться
  • Префикс все таблицы с dbo. для предотвращения перекомпиляций.
  • планы запросов Представления и поиск на сканирования таблицы/индекса.
  • В 2005, обыскивайте представления управления для пропавших без вести индексов.
0
ответ дан 24 November 2019 в 00:53
поделиться

Удалите курсоры везде, где не neceesary.

1
ответ дан 24 November 2019 в 00:53
поделиться

Не снабжайте префиксом названия Хранимой процедуры "SP _", потому что системные процедуры, которые все запускают с "SP _", и SQL Server, должны будут искать тяжелее для нахождения процедуры, когда это называют.

0
ответ дан 24 November 2019 в 00:53
поделиться
SET NOCOUNT ON

Обычно первая строка в моих хранимых процедурах, если я на самом деле не должен использовать @@ROWCOUNT.

1
ответ дан 24 November 2019 в 00:53
поделиться

В SQL Server используйте nolock директиву. Это позволяет избранной команде завершаться, не имея необходимость ожидать - обычно другие транзакции для окончания.

SELECT * FROM Orders (nolock) where UserName = 'momma'
1
ответ дан 24 November 2019 в 00:53
поделиться

Я высматриваю:

  • Разворачивают любые циклы КУРСОРА и преобразовывают в основанное на наборе ОБНОВЛЕНИЕ / операторы INSERT.
  • Высматривают любой код приложения что:
    • Вызовы SP, который возвращает большой набор записей,
    • Затем в приложении, проходит каждую запись и называет SP с параметрами для обновления записей.
    • Преобразовывают это в SP, который делает всю работу в одной транзакции.
  • Любой SP, который делает большую обработку строк. Это - доказательство, что данные не структурированы правильно / нормализованный.
  • Любой SP, которые изобретают велосипед.
  • Любой SP, что я не могу понять то, что он пытается сделать в течение минуты!
1
ответ дан 24 November 2019 в 00:53
поделиться

Не обязательно прием производительности sql по сути, но определенно связанный:

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

1
ответ дан 24 November 2019 в 00:53
поделиться

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

1
ответ дан 24 November 2019 в 00:53
поделиться

DavidM

Assuming MySQL здесь, использование ОБЪЯСНЯЕТ для обнаружения то, что продолжает запрос, удостоверьтесь, что индексы используются максимально эффективно...

В SQL Server, план выполнения получает Вас то же самое - это говорит Вам, какие индексы поражаются, и т.д.

1
ответ дан 24 November 2019 в 00:53
поделиться

Индексируйте таблицу (таблицы) clm (s), Вы фильтруете

1
ответ дан 24 November 2019 в 00:53
поделиться

Выполнение использования запроса С (NoLock) является в значительной степени стандартной операцией в моем месте. Любой поймал рабочие запросы на таблицах десятков гигабайтов без него, вынут и застрелен.

2
ответ дан 24 November 2019 в 00:53
поделиться

Немного вне темы, но если Вы управляете этими проблемами...
Высокий уровень и Высокое Влияние.

  • Для высоких сред IO удостоверяются, что Ваши диски или для RAID 10 или для RAID 0+1 или некоторая вложенная реализация набега 1 и совершают рейд 0.
  • не используют диски меньше, чем 1500K.
  • Удостоверяются, что Ваши диски только используются для Вашей Базы данных. IE никакой вход никакой ОС.
  • Выключают автоматический, растут или подобная функция. Позвольте базе данных использовать все устройство хранения данных, которое ожидается. Не обязательно, что в настоящее время используется.
  • разрабатывают Вашу схему и индексы для запросов типа.
  • , если это - таблица типа журнала (вставляют только) и должен быть в DB, не индексируют его.
  • , если Ваше выполнение выделяет создания отчетов (комплекс выбирает со многими соединениями) затем необходимо посмотреть на создание хранилища данных со схемой "звезда" или схемой "снежинка".
  • не боятся тиражирования данных в обмен на производительность!
18
ответ дан 24 November 2019 в 00:53
поделиться
  1. Имеют довольно хорошую идею оптимального пути выполнения запроса в Вашей голове.
  2. Проверка план запросов - всегда.
  3. Включают СТАТИСТИКУ, так, чтобы можно было исследовать и IO и производительность ЦП. Внимание на снижение тех чисел, не обязательно время запроса (поскольку это может быть под влиянием другого действия, кэша, и т.д.).
  4. Ищут большие количества строк, входящих в оператор, но выход небольших чисел. Обычно, индекс помог бы путем ограничения количества входящих строк (который сохраняет чтение с диска).
  5. Внимание на самое большое поддерево стоимости сначала. Изменение того поддерева может часто изменять весь план запросов.
  6. Типичные проблемы, которые я видел:
    • , Если существует много соединений, иногда SQL-сервер примет решение развернуть соединения и затем применить операторы Where. Можно обычно фиксировать это путем перемещения ГДЕ условия в пункт СОЕДИНЕНИЯ или полученная таблица со встроенными условиями. Представления могут вызвать те же проблемы.
    • Субоптимальные соединения (ЦИКЛ по сравнению с ХЕШЕМ по сравнению со СЛИЯНИЕМ). Мое эмпирическое правило состоит в том, чтобы использовать соединение ЦИКЛА, когда верхний ряд имеет очень немного строк по сравнению с нижней частью, СЛИЯНИЕ, когда наборы примерно равны и заказаны, и ХЕШ для всего остального. Добавление подсказки соединения позволит Вам протестировать свою теорию.
    • сниффинг Параметра. Если Вы работали, сохраненный proc с нереалистичными значениями сначала (скажите для тестирования), то кэшируемый план запросов может быть субоптимальным для Ваших постановочных достоинств. Выполнение снова С ПЕРЕКОМПИЛИРОВАЛО, должен проверить это. Поскольку некоторые сохранили procs, особенно те, которые имеют дело с переменными размерными диапазонами (скажите, все даты между сегодня и вчера - который повлек бы за собой, что ИНДЕКС ИЩЕТ - или, все даты между прошлым годом и в этом году - который был бы более обеспечен с ИНДЕКСНЫМ СКАНИРОВАНИЕМ), Вам, вероятно, придется работать, это С ПЕРЕКОМПИЛИРОВАЛО каждый раз.
    • Плохое добавление отступа... Хорошо, таким образом, SQL-сервер не имеет проблемы с этим - но я верная находка это невозможный понять запрос, пока я не согласовал форматирование.
19
ответ дан 24 November 2019 в 00:53
поделиться

Прием, который я недавно изучил, - то, что SQL Server может обновить локальные переменные, а также поля в операторе обновления.

UPDATE table
SET @variable = column = @variable + otherColumn

Или более читаемая версия:

UPDATE table
SET
    @variable = @variable + otherColumn,
    column = @variable

я использовал это для замены сложных курсоров/соединений при реализации рекурсивных вычислений и также получил много в производительности.

Вот детали и пример кода который сделаны фантастическими улучшениями производительности: http://geekswithblogs.net/Rhames/archive/2008/10/28/calculating-running-totals-in-sql-server-2005---the-optimal.aspx

6
ответ дан 24 November 2019 в 00:53
поделиться

CREATE INDEX

Гарантируют, что существуют индексы, доступные для Вашего WHERE и JOIN пункты. Это ускорит доступ к данным значительно.

, Если Ваша среда витрина данных или склад, , индексы должны иметься в большом количестве почти для любого мыслимого запроса.

В транзакционная среда , количество индексов должно быть ниже и их определения, более стратегические так, чтобы ведение индексов не ослабляло ресурсы. (Ведение индексов состоит в том, когда листы индекса должны быть изменены для отражения изменения в базовой таблице, как с INSERT, UPDATE, и DELETE операции.)

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

SELECT   i.make, i.model, i.price
FROM     dbo.inventory i
WHERE    i.color = 'red'
  AND    i.price BETWEEN 15000 AND 18000

у Price обычно есть более высокая кардинальность. Может быть только несколько дюжин доступных цветов, но вполне возможно тысячи различных запрашиваемых цен.

Из этого индексного выбора, idx01 обеспечивает более быстрый путь для удовлетворения запроса:

CREATE INDEX idx01 ON dbo.inventory (price, color)
CREATE INDEX idx02 ON dbo.inventory (color, price)

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

у меня, как было известно, было два очень похожих индекса, отличающиеся только по полевому порядку ускорить запросы (firstname, lastname) в одном и (lastname, firstname) в другом.

8
ответ дан 24 November 2019 в 00:53
поделиться

MySQL Assuming здесь, использование ОБЪЯСНЯЕТ для обнаружения то, что продолжает запрос, удостоверьтесь, что индексы используются максимально эффективно и пытаются устранить виды файла. MySQL High Performance: Оптимизация, Резервные копии, Репликация, и Больше является замечательной книгой по этой теме, как MySQL Performance Blog .

5
ответ дан 24 November 2019 в 00:53
поделиться

Преобразуйте НЕ В запросах к ЛЕВЫМ ВНЕШНИМ ОБЪЕДИНЕНИЯМ, если это возможно. Например, если Вы хотите найти все строки в Table1, которые не использованы внешним ключом в Table2, Вы могли сделать это:

SELECT *
FROM Table1
WHERE Table1.ID NOT IN (
    SELECT Table1ID
    FROM Table2)

, Но Вы получаете намного лучшую производительность с этим:

SELECT Table1.*
FROM Table1
LEFT OUTER JOIN Table2 ON Table1.ID = Table2.Table1ID
WHERE Table2.ID is null
2
ответ дан 24 November 2019 в 00:53
поделиться

@Terrapin там являются несколькими другими различиями между isnull и объединяют, которые стоит упомянуть (помимо соответствия ANSI, которое является большим для меня).

Объединяют по сравнению с IsNull

5
ответ дан 24 November 2019 в 00:53
поделиться

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

2
ответ дан 24 November 2019 в 00:53
поделиться

На всех моих временных таблицах мне нравится добавлять ограничения на уникальность данных (в соответствующих случаях) для создания индексов и первичных ключей (почти всегда).

declare @temp table(
    RowID int not null identity(1,1) primary key,
    SomeUniqueColumn varchar(25) not null,
    SomeNotUniqueColumn varchar(50) null,
    unique(SomeUniqueColumn)
)
2
ответ дан 24 November 2019 в 00:53
поделиться

Первый шаг: Посмотрите на План Выполнения запросов!
TableScan-> плохо
NestedLoop-> meh предупреждение
TableScan позади NestedLoop-> DOOM!

СТАТИСТИКА НАБОРА IO НА
ВРЕМЯ СТАТИСТИКИ НАБОРА НА

2
ответ дан 24 November 2019 в 00:53
поделиться

Иногда в SQL Server, если Вы используете ИЛИ в, где пункт он действительно поднимет с производительностью. Вместо того, чтобы использовать ИЛИ просто делают два, выбирает и объединение их вместе. Вы получаете те же результаты в 1000x скорость.

3
ответ дан 24 November 2019 в 00:53
поделиться

Я сделал это, привычка всегда использовать связывает переменные. Это возможно, связывают переменные, не поможет, если RDBMS не будет кэшировать SQL-операторы. Но если Вы не используете, связывают переменные, RDBMS не имеет шанса снова использовать планы выполнения запросов и проанализированные SQL-операторы. Сбережения могут быть огромными: http://www.akadia.com/services/ora_bind_variables.html . Я работаю главным образом с Oracle, но Microsoft SQL Server работает в значительной степени тот же путь.

, По моему опыту, если Вы не знаете, используете ли Вы, связывают переменные, Вы, вероятно, не. Если Ваш язык приложения не поддерживает их, найдите тот, который делает. Иногда можно зафиксировать запрос при помощи, связывают переменные для запроса B.

После этого, я говорю с нашим DBA для обнаружения то, что вызывает RDBMS большая часть боли. Обратите внимание, что Вы не должны спрашивать, "Почему этот запрос является медленным?" Это похоже на просьбу, чтобы Ваш доктор вынул Вас приложение. Уверенный Ваш запрос мог бы быть проблемой, но столь же вероятно, что что-то еще идет не так, как надо. Как разработчики, мы мы склонны думать с точки зрения строк кода. Если строка является медленной, зафиксируйте ту строку. Но RDBMS является действительно сложной системой, и Ваш медленный запрос мог бы быть признаком намного большей проблемы.

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

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

2
ответ дан 24 November 2019 в 00:53
поделиться

Посмотрите на, где пункт - проверяет, что использование индексов / проверяет, что ничто глупое не делается

where SomeComplicatedFunctionOf(table.Column) = @param --silly
2
ответ дан 24 November 2019 в 00:53
поделиться

Удалите вызовы функций в Sprocs, где множество строк будет вызывать функцию.

Мой коллега использовал вызовы функций (например, получение lastlogindate из идентификатора пользователя) для возврата очень широких наборов записей.

Для оптимизации я заменил вызовы функций в sproc на код функции: у меня время работы многих sproc уменьшилось с> 20 секунд до <1.

1
ответ дан 24 November 2019 в 00:53
поделиться
Другие вопросы по тегам:

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