Как устранить проблемы с производительностью с помощью оператора Oracle SQL

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

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

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

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

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

(Я использую Oracle 10.2.0.4 в Windows).

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

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)

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

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

Mark Brady 10.10.2008 22:51

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

Mike McAllister 13.02.2009 17:57
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
5
2
15 655
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Ответ принят как подходящий

Используйте Средство трассировки SQL и TKPROF.

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

Mike McAllister 19.09.2008 22:12

Это правильный путь, TRACE + TKPROF расскажет вам, что именно делает ваша сессия и на что она тратит время.

Matthew Watson 20.09.2008 07:48

табличные пространства? Я ни разу не обнаружил проблем с запросами, исследуя табличные пространства.

Mark Brady 10.10.2008 22:53

Ссылка не работает. У кого-нибудь есть новая ссылка?

mklauber 21.06.2011 19:43

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

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

Обе системы имеют одинаковые индексы, ограничения и триггеры. Сейчас мы смотрим на разные табличные пространства.

Mike McAllister 19.09.2008 22:10

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

user11318 20.09.2008 04:28

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

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

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

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

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

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

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

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

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

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

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

Mike McAllister 23.09.2008 23:16

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

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

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

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

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

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

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

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

а) по-прежнему делает то, что должен делать

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

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

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

Другие вопросы по теме

Влияние на производительность использования instanceof в Java
Как получить уведомление о том, что процесс Windows максимизирует процессор?
Сопровождение автоматизированного тестирования пользовательского интерфейса браузера
Есть ли обратная сторона избыточных квалификаторов? Какая-нибудь выгода?
Есть ли способ изменить компилятор .NET JIT, чтобы повысить производительность по сравнению с временем компиляции?
Где я могу найти самый быстрый в мире способ внедрения?
Какой алгоритм хеширования лучше всего использовать для строки stl при использовании hash_map?
Какой лучший инструмент для отслеживания использования памяти процессом в течение длительного периода времени в Windows?
Каковы преимущества и недостатки DTO с точки зрения производительности веб-сайта?
Самый быстрый способ найти объекты из коллекции, соответствующие условию строкового члена