2008-10-24 2 views
17

Мне было поручено оптимизировать некоторые sql-запросы на работе. Все, что я нашел, указывает на использование Explain Plan для выявления проблемных областей. Проблема, которую я не могу точно определить, что объясняет мне план объяснения. Вы получаете Cost, Cardinality и байты.Как использовать Explain Plan для оптимизации запросов?

Что это значит, и как я должен использовать это в качестве руководства. Являются ли низкие цифры лучше? Чуть лучше? Любой вход был бы весьма признателен.

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

ответ

8

Вы получите больше, чем это на самом деле, в зависимости от того, что вы делаете. Проверьте эту страницу explain plan. Я немного предполагаю, что вы используете Oracle и знаете, как запустить скрипт для отображения вывода плана. Что может быть более важно для начала, это смотреть на левую сторону для использования определенного индекса или нет и как этот индекс используется. Вы должны видеть такие вещи, как «(Полный)», «(по индексу Rowid)» и т. Д., Если вы делаете объединения. Стоимость будет следующей вещью, на которую следует обратить внимание, при этом более низкие затраты будут лучше, и вы заметите, что если вы делаете соединение, которое не использует индекс, вы можете получить очень большую стоимость. Вы также можете прочитать подробности о explain plan columns.

+0

Я ценю вам помощь, и особенно ссылки. Сейчас это делается для меня. Спасибо еще раз за помощь. –

+1

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

6

У вас есть нечеткий конец леденца.

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

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

Серьезно, получить книгу Льюиса Джонатана по стоимости на основе Oracle Fundementals

Получить книгу Тома Кайта на архитектуре баз данных Oracle и арендовать домик в лесу в течение нескольких недель.

+0

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

+1

Не добавляйте их в очередь ... перемещайте их вверх и делайте все возможное, чтобы их прочитать. Сначала я бы сказал книгу Льюиса. Это полностью связано с тем, что означает план объяснения, хотя он не написан таким образом. –

4

Это обширная область знаний (ака черное искусство).

Подход, который я обычно беру это:

  1. Выполнение оператора SQL в вопросе,
  2. Получить реальный план (смотреть DBMS_XPLAN)
  3. Сравнить расчетное количество строк (по мощности) против фактическое количество строк. Большая разница указывает на проблему, которая должна быть исправлена ​​(например, индекс, гистограмма)
  4. Рассмотрите, можете ли вы создать индекс для ускорения части процесса (обычно, когда вы концептуально думаете, что план должен идти первым). Попробуйте некоторые индексы.

Вам необходимо понять влияние O() различных индексов в контексте того, что вы запрашиваете в базе данных. Это поможет вам понять структуры данных, такие как b-деревья, хеш-таблицы и т. Д. Затем создайте индекс, который может работать и повторять процесс.

Если Oracle решит не использовать ваш индекс, примените подсказку INDEX() и посмотрите на новый план. Стоимость будет больше, чем план, который он выбрал - вот почему он не выбрал ваш индекс.Предполагаемый план может привести к некоторому пониманию того, почему ваш индекс не очень хорош.

+0

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

7

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

Несколько советов следовать:

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

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

В частности, ищите фразу «Cartesian Join» в плане объяснения. Если вы видите это, шансы ужасно хорошие, что вы нашли непреднамеренное декартовое соединение. Обычным шаблоном для непреднамеренного декартового объединения является то, что предложение FROM отображает таблицы, разделенные запятой, и условия соединения находятся в предложении WHERE. За исключением того, что отсутствует одно из условий соединения, так что у Oracle нет выбора, кроме как выполнить декартовое соединение. С большими таблицами это катастрофа производительности.

Можно увидеть картезианскую вставку в плане объяснения, где запрос логически корректен, но я ассоциирую это со старыми версиями Oracle.

Также ищите неиспользуемый составной индекс. Если первый столбец составного индекса не используется в запросе, Oracle может использовать индекс неэффективно или вообще не использовать. Позвольте мне привести пример:

Запрос был:

select * from customers  
where 
    State = @State 
    and ZipCode = @ZipCode 

(СУБД не Oracle, поэтому синтаксис был другим, и я забыл оригинальный синтаксис).

Быстрый просмотр в индексах показал индекс для клиентов со столбцами (Страна, штат, ZipCode) в указанном порядке. Я изменил запрос читать

select * from customers 
    where Country = @Country 
     and State = @State 
     and ZipCode = @ZipCode 

и теперь он побежал в течение примерно 6 секунд, а не около 6 минут, потому что оптимизатор мог использовать индекс для хорошего преимущества. Я спросил программистов о том, почему они не указали страну из критериев, и это был их ответ: они знали, что все адреса имеют страну равную «США», поэтому они решили, что могут ускорить запрос, оставив этот критерий!

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

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

Удача при достижении скорости при оптимизации!

+0

Спасибо за совет. Я также столкнулся с проблемой Cartesian Join, о которой вы говорили выше, в нескольких других запросах, над которыми работала, и это во многом повлияло на время, и теперь запросы фактически возвращают то, что они предполагают. Идите фигуру. –

Смежные вопросы