Есть проблемы с использованием подхода статического запроса; также будьте очень осторожны при использовании параметра CURSOR_SHARING = FORCE - он может действительно поднять вашу систему, если вы не провели тест покрытия, чтобы гарантировать, что все ваши другие запросы будут работать так, как вы хотите.
Проблемы со статическими запросами:
Предикаты (x равен нулю или x = col), как правило, убивают любой шанс использования индексов. Поскольку план запроса вычисляется при первом анализе запроса, используемые вами индексы будут основаны на значениях для первого запуска запроса; последующие прогоны, которые могут не ограничиваться теми же столбцами, будут по-прежнему использовать те же индексы.
Наличие одного статического оператора с переменными подстановки не позволит оптимизатору сделать разумный выбор в отношении того, какой индекс использовать на основе распределения данных. В динамическом запросе (или при первом запуске запроса с переменными связывания) Oracle увидит, насколько избирательным является ваше ограничение; очень избирательное ограничение станет основным кандидатом на использование индекса. Например, если в вашей таблице есть строка для каждого человека в США, STATE = 'Аляска' будет гораздо более вероятно использовать индекс STATE, чем STATE = 'Калифорния'.
Конечно, в обоих этих случаях, если динамические столбцы в предложении WHERE все равно не проиндексированы, это не имеет значения, хотя я был бы удивлен, если бы это было в базе данных того размера, о котором вы говорите о.
Кроме того, учтите реальную стоимость всего этого сложного анализа. Да, жесткий анализ сериализует системные ресурсы, что делает их дорогими, но только в контексте запросов большого объема . По своей природе специальные запросы выполняются не очень часто. Стоимость, которую вы платите за все сложные анализы, которые вы выполняете за целый день, вероятно, будет в сотни раз меньше стоимости одного запроса, который использует неправильные индексы.
В прошлом я реализовывал эти системы почти так же, как вы это делали здесь - базовую часть запроса, затем перебирал список ограничений и добавлял предикаты предложения WHERE. Я не думаю, что кому-то сложно поддерживать или понимать, особенно если вы говорите об ограничениях, которые не включают добавление большого количества подзапросов или дополнительных таблиц в предложение FROM.
Стоит учесть одну вещь: если эта система в основном автономна (другими словами, она не постоянно обновляется или не вставляется - заполняется периодическими загрузками объемных данных), вам может понадобиться использовать индексы BITMAP. Растровые индексы отличаются от обычных индексов b-дерева тем, что несколько индексов в одной таблице могут использоваться одновременно, и индексы битовой карты на диске намного, намного меньше, чем b-деревья. Они очень хорошо работают для таких приложений, как здесь, где у вас будет множество ограничений, которые не могут быть определены во время разработки. Вам нужно будет размещать растровые индексы только в столбцах с относительно небольшим количеством различных значений, скажем, одно значение составляет не менее 1/1000 таблицы, поэтому не используйте растровые изображения для уникальных столбцов.
Однако недостатком является то, что растровые индексы заметно ухудшат производительность вставок и обновлений. Лучшая практика для растровых изображений - использовать их в приложениях хранилища данных, и они отбрасываются до загрузки и воссоздаются после нее.