В предыдущем разделе обсуждались вопросы локальной оптимизации. Кроме того, имеются аспекты, связанные с композицией или декомпозицией операций.
Параметризуемые запросы (R1). Параметризуемые и динамические запросы возникают при извлечении запросов из программы для их удаленного выполнения в базе данных. Например, при извлечении запроса из кода с ортогональной персистентностью, показанного на рис. 2, для его явного выполнения в виде SQL-запроса (см. рис. 3) префикс фамилии служащего становится параметром запроса. При явном выполнении запросов трудно специфицировать параметры запросов, и типы параметров не проверяются до времени выполнения.
Динамические запросы (R2). Динамические запросы – это запросы, которые представляются в виде символьных строк, конструируемых во время выполнения программы. Хотя идея динамических запросов может казаться ужасной, они достаточно распространены, и от них не следует сходу отказываться. Динамические запросы могут обрабатываться путем частичного выполнения запроса на основе данных, которые влияют на запрос, но не зависят от базы данных []. Например, если в поисковой форме пользовательского интерфейса допускается указание набора необязательных критериев поиска, то результирующий запрос можно частично вычислить для конкретного набора критериев. Подробное объяснение приводится в []. Динамические запросы также возникают при реализации тонких правил авторизации, применяемых индивидуально к каждому пользователю []. Мы полагаем, что отсутствие поддержки динамических запросов является основной причиной отказа от большинства форм встраиваемого SQL [].
Динамические запросы также требуются для создания произвольных соединений (ad-hoc joins) в приложениях, поддерживающих оперативную аналитическую обработку (OLAP). Такие приложения в этой статье не обсуждаются.
Модульные запросы (R3). Поскольку в большинстве языков программирования общего назначения имеется поддержка модульной декомпозиции – с использованием функциональной абстракции и абстракции данных, – у соответствующих персистентных языков имеются те же возможности. Хорошо известно, что модульность может мешать оптимизации, но в контексте доступа к базам данных эта проблема может еще более усложниться. И поисковая, и навигационная оптимизация зависят от знания всех условий и данных, участвующих в доступе к персистентным данным. Оптимизация запросов лучше всего работает в тех случаях, когда базе данных поручается выполнение больших частей работы, а не отдельных операций. Тогда сокращается число взаимодействий приложения с базой данных, а оптимизатор получает больший простор для оптимизации. Важно заметить, что, хотя в реляционной алгебре поддерживается модульная композиция, поскольку каждый запрос является отношением, на практике может быть достаточно трудно комбинировать результаты двух SQL-запросов на семантическом уровне. В решении проблемы интеграции языков и баз данных следует поддерживать модульность, композицию и повторное использование структур программ, обрабатывающих большие объемы данных.