Параллельное выполнение отдельного SQL-запроса означает его разбиение на части, их одновременную обработку и выдачу общего результата. Параллельно могут выполняться все действия в рамках запроса или только некоторые. При этом значительно сокращается время обработки SQL-предложения, особенно если требуется прочесть и проанализировать большое количество данных.
Основной единицей параллелизма является виртуальный процессор доступа (Access Module Processor). Все запросы и операции загрузки данных, резервного копирования, построения индексов распределяются между AMP. В первой версии AMP были физическими процессорами, но затем стали виртуальными. На отдельном SMP-узле (Symmetric MultiProcessor — «симметричная многопроцессорность») могут работать несколько AMP, реализованных в виде процессов операционной системы, а все такие узлы объединяются в систему с массовой параллельной обработкой (Massively Parallel Processing, MPP). Процессоры AMP позволяют распределять ресурсы, распараллеливая все операции.
В СУБД Teradata параллельная обработка запросов осуществляется на основе хеш-секционирования данных и их распределения между всеми процессорами AMP. Перед началом работы, на этапе конфигурирования, задается число процессоров AMP — от двух до двадцати на узел, в зависимости от мощности базовых аппаратных средств. Все операции, такие как сканирование таблиц и индексов, проекция, выборка, соединение, агрегирование и сортировка данных, распределяются между процессорами AMP и выполняются параллельно. Каждая операция с данными, отнесенными к одному процессору AMP, выполняется независимо от операций других AMP.
Внутренним параллелизмом называют перекрытие по времени отдельных операций с базой данных. Оптимизатор разбивает SQL-запрос на несколько высокоуровневых операций, называемых шагами, и направляет их AMP для выполнения. Часто шаг является довольно большим фрагментом работы и может быть простым (таким как сканирование таблицы и возврат результата) или сложным (сканирование двух таблиц с отбором строк, соединение таблиц, перераспределение результатов соединения по указанным столбцам, сортировка перераспределенных строк и размещение результатов в промежуточной таблице). В пределах каждого из таких шагов несколько операций выполняются параллельно с помощью конвейерной обработки. При сканировании таблиц отобранные строки могут по конвейеру отправляться в процесс соединения.
Конвейеризация четырех действий одного шага SQL на каждом процессоре AMP |
Конвейерная обработка позволяет начать следующее действие прежде, чем закончено предыдущее. Она выполняется при любой возможности в пределах каждого шага.
Внешний параллелизм — это дополнительный уровень распараллеливания операций. Он реализуется за счет одновременного выполнения нескольких шагов запроса всеми компонентами организации параллелизма. Для выполнения любого шага операции над базой данных на каждом AMP активизируются один или несколько процессов. Несколько шагов запроса могут выполняться одновременно, если они не зависят от результатов предыдущих шагов.
Рисунок 2 |
На рис. 2 показана система с четырьмя AMP и запрос, разделенный оптимизатором на семь шагов. Шаг 2.2 (аналогичный шагу 1.2) соответствует внутреннему параллелизму: сканируются и соединяются две таблицы, Lineitem и Order. Все три действия выполняются конвейерным методом в пределах одного шага. Шаги 1.1 и 1.2, как и шаги 2.1 и 2.2, демонстрируют многошаговый параллелизм, при котором каждый процессор AMP выполняет два шага одновременно.
В дополнение к методам параллельной обработки, показанным на рис. 2, предлагается расширение SQL, называемое Multi-Statement Request («запрос, состоящий из нескольких предложений»), позволяющее связать несколько предложений SQL и направить их оптимизатору как единое целое. СУБД пытается выполнить эти предложения параллельно, причем все общие подвыражения обрабатываются однократно, а результаты поступают в общее пользование. Соответствующий метод известен как «исключение общих подвыражений». Если связать вместе шесть предложений выбора SELECT, содержащих один и тот же подзапрос, последний будет выполнен только один раз. Но даже если предложения SQL зависят друг от друга и выполняются с перекрытием по времени, каждое из них возвратит собственный независимый результат.