Как часто oracle пересматривает план запроса? - PullRequest
2 голосов
/ 14 октября 2011

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

select * from FOO_TABLE where ID > ?

в сочетании с:

stmt.setMaxRows(5000);

в Java для ограничения количества записей, выбранных в одном чанке.(Мы не хотим использовать МЕЖДУ здесь, потому что идентификаторы имеют пробелы).И мы продолжаем обрабатывать фрагменты 5000 до тех пор, пока тест не будет остановлен.

Теперь производительность нашего приложения со временем падает, и когда я проверил, что происходит на стороне Oracle, я с удивлением заметил, что план запроса дляmsgstr "выбрать * из FOO_TABLE, где ID>?"выполняет сканирование таблицы вместо использования индекса PK для идентификатора.

После перезапуска нашего приложения (но без усечения таблицы) Oracle вернулся к причине и использовал индекс PK.

Итак, мойобъяснение состояло в том, что Oracle считал хорошей идеей сканировать таблицу, когда она была почти пустой, но затем никогда не пересматривал этот план запроса.Это подводит меня к моему вопросу: как часто oracle пересматривает план запроса?

Было ли это потому, что я перезапустил наше приложение?У меня есть некоторые сомнения по этому поводу, поскольку мы перезапускаем наши объединенные соединения через 1 час (следовательно, ни одно соединение не может быть старше 1 часа).

Было ли это потому, что прошло определенное количество времени?

Как бы вы заставили oracle не выполнять сканирование, даже если таблица почти пуста?

Информация об окружении: - oracle 11g - jdbc client (java 6)

ОБНОВЛЕНИЕ 25.10.2011Я провел регрессионный тест на Oracle 10g, и проблема та же, поэтому он не вызван и не исправлен динамическим разделением курсора.Как отмечал Марк вначале, план не будет пересматриваться, если не произойдет серьезное событие, такое как структурные изменения или пересчет статистики таблицы.

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

Ответы [ 4 ]

2 голосов
/ 24 августа 2013

Если запрос неэффективен, потому что вы используете устаревшую статистику, как, как представляется, здесь, то ответ, как правило, заключается в сборе статистики.

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

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

2 голосов
/ 24 августа 2013

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

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

2 голосов
/ 14 октября 2011

Какая версия Oracle?

Как правило,

select * from FOO_TABLE where ID > ?

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

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

11g имеет адаптивное совместное использование курсоров (именно поэтому я спросил версию Oracle), ине вдаваясь в подробности, он будет смотреть на значения переменных связывания и определять необходимость изменения плана на основе нового значения связывания.

1 голос
/ 15 октября 2011

Адаптивное совместное использование курсора является встроенной функцией оптимизатора, начиная с 11.1.Какую версию Oracle вы используете?(Полный номер версии?) Я ожидаю, что более поздние версии 11g, то есть 11.2.0.2, 11.2.0.3 будут вести себя лучше.

Обсуждение входов и выходов адаптивного совместного использования курсора, вероятно, выходит за рамкиобласть действия этого форума, но см. здесь хорошее обсуждение этого вопроса: http://blogs.oracle.com/optimizer/entry/update_on_adaptive_cursor_sharing

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

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