2.2.5.1 На чем основана технология PDQ
Реализация запроса состоит из отдельных действий - сканирования, сортировки, группирования и др. Эти действия называются итераторами. Итераторы образуют дерево реализации запроса в том смысле, что результаты выполнения одних итераторов являются исходными данными для других. При обычной обработке итераторы выполняются последовательно. В основе технологии PDQ лежат следующие виды оптимизации и регулирования:
Параллельный ввод и вывод (на основе горизонтальной фрагментации таблиц).Распараллеливание отдельных итераторов (на основе методов разбиения данных).Распараллеливание плана выполнения запроса (путем разбиения дерева реализации запроса на независимые поддеревья; за счет применения техники потоков данных).Снижение вычислительной сложности алгоритмов (применение основанных на хешировании алгоритмов сортировки, соединения, вычисления агрегатных функций (sum, min, max, avg, ...)).Управление ресурсами, регулирование степени распараллеливания (под PDQ выделяется определенная доля системных ресурсов).
Итератор - это программный объект, который осуществляет итеративную (циклическую) обработку некоторого множества данных. Итераторы различаются типом производимой обработки, но имеют единообразный внешний интерфейс. Каждый итератор открывает один (или более) входных потоков данных (data flow), последовательно считывает их и, после обработки, помещает результаты в выходной поток. Итератору безразличен источник входного потока и назначение выходного потока - это может быть диск, другой итератор, сетевое соединение. Мы будем говорить о поставщиках и потребителях потоков данных. Ниже перечислены типы итераторов, применяемые в INFORMIX-OnLine DS:
SCAN - Сканирует фрагментированные и нефрагментированные таблицы и индексы. NESTED LOOP JOIN - Реализует стандартную логику соединений методом вложенных циклов (читает строку из одной таблицы, находит все совпадения во второй таблице, читает следующую строку из первой таблицы и т. д.). MERGE JOIN - Выполняет фазу слияния для соединения методом сортировки и слияния. HASH JOIN - Реализует новый метод соединений с хешированием. Для одной из двух соединяемых таблиц строится хеш-таблица, вторая таблица зондируется. Оптимизатор решает, какая из таблиц будет хешироваться. GROUP - Группирует данные (GROUP BY) и вычисляет агрегатные функции. SORT - Сортирует данные. MERGE - Выполняет объединения UNION и UNION ALL (для UNION используется комбинация итераторов MERGE и SORT). REMOTE - Реализует удаленные сканирования для операторов SELECT.
Итератор как программный объект состоит из статических и динамических структур данных. Статическая структура содержит ссылки на функции (или методы), применимые к итератору. Динамическая структура содержит информацию о текущем состоянии итератора (открыт, закрыт, выполняет очередную итерацию), одну или две ссылки на поставщиков.
Методы итератора
CREATE() - Создает итератор. Выделяет память для итератора, инициализирует его структуры, а также остальные методы (open(), next(), close(), free()), т.е. устанавливает ссылки на функции, соответствующие данному типу итератора. Затем вызывает метод create() для своих итераторов-поставщиков, которые создадут своих поставщиков, если таковые имеются, и т. д. Таким образом, вызов метода create() для корневого итератора приводит к созданию всего дерева итераторов.
OPEN() - Запускает итератор. Выполняются специфические для данного типа итератора инициализирующие действия, возможно, запрос дополнительной памяти. Например, при запуске итератора сканирования определяется, какие фрагменты необходимо сканировать, устанавливается указатель на первый из них, создается временная таблица (если она нужна), посылается сообщение
MGM (MGM - компонента сервера, которая регулирует выделение ресурсов под запросы, обрабатываемые средствами PDQ; см. об этом ниже, п. "Баланс между OLTP и DSS-приложениями") о запуске потока сканирования. Далее применяется метод open() по отношению к поставщикам итератора, которые применят его к своим поставщикам и т.д. Таким образом, для запуска всего дерева итераторов достаточно применить метод open() к корневому итератору.