Вопрос по performance, database – Как устранить проблемы с производительностью с помощью оператора SQL SQL

5

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

Обе схемы имеют 99% одинаковую структуру. Несколько столбцов имеют немного разные имена, за исключением того, что они одинаковы. Операторы вставки практически одинаковы. План объяснения для одного дает стоимость 6, план объяснения для другого дает стоимость 7. Таблицы, включенные в оба набора операторов вставки, имеют абсолютно одинаковые индексы. Статистика была собрана для обеих схем.

Один оператор вставки вставляет 12 000 записей за 5 секунд.

Другой оператор вставки вставляет 25 000 записей за 4 минуты 19 секунд.

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

(Я использую Oracle 10.2.0.4 на коробке Windows).

Edit: В итоге проблема заключалась в неэффективном плане запросов, включающем декартово слияние, которое не нужно было выполнять. Разумное использование индексных подсказок и подсказок хеш-соединения решило проблему. Теперь это занимает 10 секунд. Sql Trace / TKProf дал мне направление, поскольку я показал, сколько секунд занял каждый шаг в плане, и сколько строк генерировалось. Таким образом, TKPROF показал мне:

<code>Rows     Row Source Operation
-------  ---------------------------------------------------
  23690  NESTED LOOPS OUTER (cr=3310466 pr=17 pw=0 time=174881374 us)
  23690   NESTED LOOPS  (cr=3310464 pr=17 pw=0 time=174478629 us)
2160900    MERGE JOIN CARTESIAN (cr=102 pr=0 pw=0 time=6491451 us)
   1470     TABLE ACCESS BY INDEX ROWID TBL1 (cr=57 pr=0 pw=0 time=23978 us)
   8820      INDEX RANGE SCAN XIF5TBL1 (cr=16 pr=0 pw=0 time=8859 us)(object id 272041)
2160900     BUFFER SORT (cr=45 pr=0 pw=0 time=4334777 us)
   1470      TABLE ACCESS BY INDEX ROWID TBL1 (cr=45 pr=0 pw=0 time=2956 us)
   8820       INDEX RANGE SCAN XIF5TBL1 (cr=10 pr=0 pw=0 time=8830 us)(object id 272041)
  23690    MAT_VIEW ACCESS BY INDEX ROWID TBL2 (cr=3310362 pr=17 pw=0 time=235116546 us)
  96565     INDEX RANGE SCAN XPK_TBL2 (cr=3219374 pr=3 pw=0 time=217869652 us)(object id 272084)
      0   TABLE ACCESS BY INDEX ROWID TBL3 (cr=2 pr=0 pw=0 time=293390 us)
      0    INDEX RANGE SCAN XIF1TBL3 (cr=2 pr=0 pw=0 time=180345 us)(object id 271983)
</code>

Обратите внимание на строки, в которых выполняются операции MERGE JOIN CARTESIAN и BUFFER SORT. На это я обратил внимание на количество сгенерированных строк (более 2 миллионов!) И количество времени, затрачиваемого на каждую операцию (по сравнению с другими операциями).

Облако и арбуз на 99% одинаковы - вода ... не означает, что они эквивалентны. У меня может быть два огромных запроса, которые идут на страницы и меняют = на! =, И это может полностью изменить производительность. Mark Brady
Mark - операторы вставки были в двух разных схемах с одинаковыми таблицами, несколько столбцов названы по-разному. Типы данных были одинаковыми. Оператор вставки использовал те же таблицы, ту же стратегию соединения и т. Д. Mike McAllister

Ваш Ответ

9   ответов
-1

analyzing the oI also highly recommend the book Optimizing Oracle Performance, which discusses similar tools for tracing execution and utput.

0

SQL Trace и tkprof хороши, только если у вас есть доступ к этим инструментам. Большинство крупных компаний, в которых я работаю, не позволяют разработчикам получать доступ к чему-либо под Oracle Unix ID.

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

Error: User Rate Limit Exceeded Mike McAllister
1

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

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

Что дальше? Ну, есть множество стратегий, чтобы настроить плохие высказывания. Первый вариант, который я бы предложил, если вы используете Oracle 10g, - это попробоватьСоветник по настройке SQL чтобы увидеть, скажет ли Oracle более подробный анализ ошибки своих путей. Затем он может сохранить этот план, и вы будете использовать более эффективный план.

Если вы не можете этого сделать, или если это не сработает, то вам нужно заняться такими вещами, как предоставление подсказок к запросам, наброски хранимых вручную запросов и тому подобное. Это сложная тема. Вот где это помогает иметь настоящий DBA. Если вы этого не сделаете, вы захотите начать читатьдокументацияНо учтите, что есть чему поучиться. (Oracle также имеет класс настройки SQL, который является или, по крайней мере, раньше, был очень хорошим. Хотя это не дешево.)

0

Когда производительность оператора SQL не соответствует ожидаемой / желаемой, первое, что я делаю, это проверяю план выполнения.

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

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

С помощью двух операторов для сравнения вы можете явно сравнить два плана выполнения, чтобы увидеть, чем они отличаются.

Из этого анализа я придумываю план выполнения, который, я думаю, должен подходить лучше. Это не точный план выполнения, а лишь некоторые важные изменения, которые я нашел, например: он должен использовать Index X или Hash Join вместо вложенного цикла.

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

а) все еще делает то, что должен делать

б) на самом деле быстрее

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

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

2

Основными виновниками замедления вставки являются индексы, ограничения и триггеры oninsert. Проведите тест, не удалив столько из них, сколько сможете, и посмотрите, быстро ли он. Затем введите их обратно и посмотрите, кто из них вызывает проблему.

Я видел системы, где они сбрасывали индексы перед массовым вставлением и перестраивали в конце - и это быстрее.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Mike McAllister
4
Error: User Rate Limit Exceeded Mike McAllister
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
1

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

Любимые трюки настройки производительности

... Он может быть полезен в качестве контрольного списка, даже если он не специфичен для Oracle.

0

Я согласен с предыдущим постером, что SQL Trace и tkprof - хорошее место для начала. Я также очень рекомендую книгуОптимизация производительности Oracle, в котором рассматриваются аналогичные инструменты для отслеживания выполнения и анализа выходных данных.

0

Еще одна хорошая справка, представляющая общий метод настройки запросов, - книгаНастройка SQL Дэном Тау.

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