Когда производительность оператора SQL не соответствует ожидаемой / желаемой, я сначала проверяю план выполнения.
Хитрость в том, чтобы проверять вещи, которые не соответствуют ожиданиям. Например, вы можете найти сканирование таблицы, где вы думаете, что сканирование индекса должно быть быстрее или наоборот.
Точкой, в которой оптимизатор оракула иногда делает неправильный поворот, являются оценки того, сколько строк вернет шаг. Если план выполнения ожидает 2 строки, но вы знаете, что он будет больше похож на 2000 строк, план выполнения будет меньше оптимального.
С помощью двух операторов для сравнения вы можете явно сравнить два плана выполнения, чтобы увидеть, чем они отличаются.
Из этого анализа я придумываю план выполнения, который, по моему мнению, должен подходить лучше. Это не точный план выполнения, а лишь некоторые важные изменения, которые я нашел, например: он должен использовать Index X или Hash Join вместо вложенного цикла.
Далее нужно выяснить, как заставить Oracle использовать этот план выполнения. Часто с помощью подсказок или создания дополнительных индексов, иногда меняя оператор SQL. Тогда конечно проверьте, что изменилось утверждение
а) все еще делает то, что должен
б) на самом деле быстрее
С b очень важно убедиться, что вы тестируете правильный вариант использования. Типичным падением ямы является разница между возвратом первого ряда и возвращением последнего ряда. Большинство инструментов показывают первые результаты, как только они становятся доступны, без прямого указания на то, что предстоит проделать дополнительную работу. Но если ваша фактическая программа должна обработать все строки, прежде чем она перейдет к следующему этапу обработки, это почти не имеет значения, когда появляется первая строка, это имеет значение только тогда, когда последняя строка доступна.
Если вы найдете лучший план выполнения, последний шаг - заставить вашу базу данных фактически использовать ее в реальной программе. Если вы добавили индекс, это будет часто работать из коробки. Подсказки являются опцией, но могут быть проблематичными, если библиотека создает оператор SQL, те из них часто не поддерживают подсказки. В крайнем случае вы можете сохранить и исправить планы выполнения для конкретных операторов SQL. Я бы избегал такого подхода, потому что его легко забыть, и через год какой-нибудь бедный разработчик поцарапает себе голову, почему заявление работает таким образом, что могло бы быть уместно с данными год назад, но не с нынешними данные ...