При запуске теста производительности для нашего приложения для обработки данных мы начинаем с пустого 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, который соответствует критериям поиска, тогда используйте его даже для небольших таблиц (где разница в производительности незначительна).