Как вы интерпретируете план объяснения запроса?

88

При попытке понять, как выполняется инструкция SQL, иногда рекомендуется взглянуть на план объяснения. Какой процесс нужно пройти для интерпретации (осмысления) плана объяснения? Что должно выделяться как «О, это прекрасно работает?» против «О нет, это неправильно».

lbalazscs
источник

Ответы:

80

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

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

Итак, для механизма чтения плана объяснения документация Oracle является хорошим руководством: http://download.oracle.com/docs/cd/B28359_01/server.111/b28274/ex_plan.htm#PFGRF009

Также внимательно прочтите Руководство по настройке производительности.

Также есть Google для «обратной связи по количеству элементов», методики, в которой план объяснения может использоваться для сравнения оценок мощности на различных этапах запроса с фактическими значениями мощности, полученными во время выполнения. Я полагаю, что Вольфганг Брайтлинг - автор метода.

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

Дэвид Олдридж
источник
5
Я понял, что это ты после первых 9 слов. Это похоже на «назови эту мелодию» ... Я могу определить сообщение Дэйва А в n словах или меньше ...
Я бы немного поспорил с вашим использованием «большого» ... иногда данные могут быть настолько плохо сгруппированы вокруг столбцов индекса, что FTS не выполнит сканирование индекса даже для 10% строк ...
1
На 10% - абсолютно. Если у вас 200 строк в блоке и вы ищете 0,5% строк, то теоретически вам может потребоваться доступ к 100% блоков, чтобы получить все значения в любом случае, так что это становится еще более экстремальным, чем 10%.
Дэвид Олдридж
5

Два примера ниже показывают ПОЛНОЕ сканирование и БЫСТРО сканирование с использованием ИНДЕКСА.

Лучше всего сконцентрироваться на стоимости и мощности. Если посмотреть на примеры, то использование индекса снижает стоимость выполнения запроса.

Это немного сложнее (и у меня нет 100% -ной обработки), но в основном стоимость зависит от затрат ЦП и ввода-вывода, а мощность - это количество строк, которые Oracle ожидает проанализировать. Уменьшение обоих из них - это хорошо.

Не забывайте, что на стоимость запроса могут влиять ваш запрос и модель оптимизатора Oracle (например, COST, CHOOSE и т. Д.), А также то, как часто вы запускаете свою статистику.

Пример 1:

СКАНИРОВАТЬ http://docs.google.com/a/shanghainetwork.org/File?id=dd8xj6nh_7fj3cr8dx_b

Пример 2 с использованием индексов:

ИНДЕКС http://docs.google.com/a/fukuoka-now.com/File?id=dd8xj6nh_9fhsqvxcp_b

И, как уже предлагалось, следите за СКАНИРОВАНИЕМ ТАБЛИЦЫ. Обычно этого можно избежать.

Марк Нольд
источник
У режима правил нет затрат ... так что я полагаю, что ваше утверждение в некотором роде верно, но я бы сказал, что оно в корне неточно. Если вы скажете CHOOSE, вы можете получить RBO или CBO. CBO - единственный, кто рассчитывает стоимость.
4

Поиск таких вещей, как последовательное сканирование, может быть в некоторой степени полезным, но реальность заключается в цифрах ... кроме тех случаев, когда цифры являются просто оценками! Что обычно гораздо полезнее, чем смотреть на план запроса, так это на фактическое выполнение . В Postgres это разница между EXPLAIN и EXPLAIN ANALYZE. EXPLAIN ANALYZE фактически выполняет запрос и получает реальную информацию о времени для каждого узла. Это позволяет увидеть, что происходит на самом деле , а не то, что, по мнению планировщика , произойдет. Много раз вы обнаружите, что последовательное сканирование вообще не проблема, а что-то другое в запросе.

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

децибел
источник
3

На самом деле для подобных проблем лучше всего использовать АСКТОМ . В частности, его ответ на этот вопрос содержит ссылки на онлайн-документ Oracle, где объясняется множество подобных правил.

Следует иметь в виду, что планы объяснения - это действительно наилучшие предположения.

Было бы неплохо научиться использовать sqlplus и поэкспериментировать с командой AUTOTRACE. Имея некоторые точные цифры, вы обычно можете принимать более правильные решения.

Но тебе стоит АСКТОМ. Он все об этом знает :)

EvilTeach
источник
2

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

Том Лейс
источник
2

Одно «О нет, это неправильно» часто имеет форму сканирования таблицы . Сканирование таблиц не использует никаких специальных индексов и может способствовать очистке всего полезного в кэшах памяти. Например, в postgreSQL это выглядит так.

Seq Scan on my_table  (cost=0.00..15558.92 rows=620092 width=78)

Иногда сканирование таблиц лучше, чем, скажем, использование индекса для запроса строк. Однако это один из тех паттернов, которые вы, кажется, ищете.

выпуклая оболочка
источник
2
(Полное) Сканирование таблиц не обязательно очищает кеш памяти.
a_horse_with_no_name
2

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

Например, если вы объединяете две таблицы, A и B в соответствующих столбцах C и D (AC = BD), и ваш план показывает сканирование кластерного индекса (термин SQL Server - не уверен в термине оракула) в таблице A, затем присоединение вложенного цикла к серии поисков кластеризованного индекса в таблице B, вы можете подумать, что возникла проблема. В этом сценарии вы можете ожидать, что движок выполнит пару сканирований индекса (по индексам в соединенных столбцах), за которыми последует соединение слиянием. Дальнейшее исследование может выявить неверную статистику, заставляющую оптимизатор выбрать этот шаблон соединения или индекс, который на самом деле не существует.

Джонатан Рупп
источник
1

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

Стивен А. Лоу
источник
1

Я в основном ищу сканирование индексов или таблиц. Обычно это говорит мне, что мне не хватает индекса для важного столбца, который находится в операторе where или операторе соединения.

С http://www.sql-server-performance.com/tips/query_execution_plan_analysis_p1.aspx :

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

* Index or table scans: May indicate a need for better or  additional indexes.
* Bookmark Lookups: Consider changing the current clustered index,
  consider using a covering index, limit
  the number of columns in the SELECT
  statement.
* Filter: Remove any functions in the WHERE clause, don't include wiews
  in your Transact-SQL code, may need
  additional indexes.
* Sort: Does the data really need to be sorted? Can an index be used to
  avoid sorting? Can sorting be done at
  the client more efficiently? 

Их не всегда можно избежать, но чем больше вы сможете их избегать, тем выше будет производительность запроса.

dpollock
источник
1
Сканирование таблиц не все плохо - в зависимости от количества записей, возвращенных / обработанных из таблицы, полное сканирование таблицы может быть быстрее, чем сканирование индекса (если вы все равно собираетесь вернуть записи, вы выполните сканирование индекса и полное чтение из таблицы - 2 шага вместо 1).
ScottCher
-7

Эмпирические правила

(вы, вероятно, тоже захотите прочитать подробности:

Плохой

Сканирование нескольких больших таблиц

Хороший

Использование уникального индекса
Индекс включает все обязательные поля

Самый частый выигрыш

Примерно из 90% наблюдаемых мною проблем с производительностью самая легкая победа - разбить запрос с большим количеством (4 или более) таблиц на 2 небольших запроса и временную таблицу.

AJ.
источник
2
Сканирование таблиц слишком часто рассматривается как плохое, и изначально это то, на чем бы сосредоточились неопытные люди. Это сильно зависит от количества записей, возвращаемых из этой таблицы, существует порог, когда быстрее выполнять полное сканирование таблицы, чем поиск по индексу.
ScottCher
8
Проголосовали за вопиющий совет. 90% проблем с производительностью НЕ решаются временными таблицами и разбиением запроса. В каком мире ты живешь ?!
TheSoftwareJedi
@Jedi, я живу в мире, где индексы в основном правильные, а базы данных в значительной степени разумно структурированы. Хотя мне было бы интересно прочитать ваш ответ.
Эй Джей.