Скачиваний:
82
Добавлен:
02.05.2014
Размер:
2.28 Mб
Скачать

17.7. Реализация реляционных операторов

В этом разделе представлено краткое описание некоторых очевидных методов реали- зации отдельных реляционных операторов, в частности оператора соединения. Включе- ние данного материала в книгу было вызвано стремлением развеять ту таинственность, которая все еще витает над описанием процесса оптимизации. Обсуждаемые далее мето- ды соответствуют механизмам, которые в разделе 17.3 были названы низкоуровневыми процедурами реализации.

Замечание. Более сложные приемы реализации описаны в аннотациях к определен- ным работам, ссылки на которые приведены в конце главы.

Для простоты предположим, что кортежи и отношения физически хранятся на диске так, как они организованы логически. Далее будет рассмотрено выполнение операторов проекции, соединения и обобщения, причем под операторами обобщения будем пони- мать оба указанных ниже основных варианта.

  1. Обобщение, результат которого не включает атрибутов.

  2. Обобщение, результат которого включает как минимум один атрибут.

Первый вариант достаточно прост. Как правило, в этом случае выполняется просмотр всего отношения, для которого вычисляется обобщающая функция, за исключением ва- рианта, когда для обобщаемого атрибута имеется индекс. В последнем случае значение обобщающей функции может быть вычислено исключительно по значениям в файле ин- декса, без необходимости обращения к самому отношению [17.35]. Например, рассмот- рим выполнение следующего запроса.

SUMMARIZE SP ADD AVG ( QTY ) AS AQ

Для вычисления его результатов достаточно просмотреть индекс по атрибуту QTY (предполагается, что такой индекс существует), вовсе не касаясь самой переменной- отношения поставок SP. Аналогичные соображения применимы и для функций COUNT и SUM (причем для функции COUNT подойдет любой индекс). Что касается функций МАХ и MIN, то их результат можно получить, выполнив единственную операцию чтения послед- ней (для функции МАХ) или первой (для функции MIN) строки индекса (здесь вновь пред- полагается, что индекс для соответствующего атрибута уже существует).

Далее в этом разделе будут рассматриваться обобщающие функции только второго типа (т.е. такие, результат вычисления которых включает значения хотя бы одного атри- бута). Ниже показан пример операции обобщения второго типа.

SUMMARIZE SP PER Р { Р# } ADD SUM ( QTY ) AS TOTQTY

С точки зрения пользователя, операции проекции, соединения и операции обобщения второго типа, конечно, абсолютно не похожи одна на другую. Но с точки зрения реализа- ции они имеют некоторое сходство, так как в каждом из случаев система должна сгруппи-

ровать кортежи на основе значений некоторых атрибутов или комбинации атрибутов, В случае операции проекции подобная группировка позволяет системе исключить кортежи- дубликаты, в случае операции соединения — найти соответствующие друг другу кортежи, а в случае операции обобщения — вычислить отдельные обобщенные значения (например, по группам). Существует несколько методов подобной группировки кортежей.

  1. Последовательный просмотр (или метод "грубой силы").

  2. Поиск по индексу.

  3. Поиск по хеш-таблице.

  4. Слияние.

  5. Хеширование.

  6. Комбинация названных выше методов.

На рис. 17.4-17.8 приведены псевдокоды процедур реализации перечисленных мето- дов для операции соединения (операции проекции и обобщения оставлены читателю в качестве упражнения). На этих рисунках используются следующие соглашения. Прежде всего, R и S — это отношения, которые должны быть соединены, а С — их общий атри- бут (возможно, составной). Предполагается, что возможен последовательный доступ к кортежам обоих отношений R и S по одному за одну операцию. Эти кортежи в последо- вательности доступа будут обозначаться как R[l], R[2], ...,R[m] и S[l], S[2], S[n] соответственно. Для соединенного кортежа, составленного из атрибутов кортежей R[i) и S[JL будет использоваться обозначение R[i] * S[j]. И наконец, переменную- отношение R будем считать внешней, а переменную-отношение S — внутренней (поскольку они управляют внешним и внутренним циклами просмотра соответственно).

Последовательный просмотр

Метод последовательного просмотра или "грубой силы" иногда также называют про- стым методом. В этом случае рассматриваются все возможные комбинации кортежей (т.е. каждый кортеж отношения R проверяется в сочетании с каждым кортежем отноше- ния S, как показано на рис. 17.4).

Замечание. Метод последовательного просмотра часто называют методом вложенных циклов, но это название нельзя считать адекватным, поскольку вложенные циклы ис- пользуются в реализациях всех названных выше методов.

do i :— 1 to m ; /* Внешний цикл */

do j := 1 to n ; /* Внутренний цикл */

if R[i].C = S[j].C then

<к результату добавить соединенный кортеж R[i] * S[j]> ; end ; end ;

Рис. 17.4. Метод последовательного просмотра

Давайте проанализируем затраты, связанные с использованием метода последова- тельного просмотра.

Замечание. Здесь мы ограничимся только анализом затрат на выполнение операций ввода-вывода, хотя на практике может потребоваться также учесть другие параметры (например, затраты времени центрального процессора).

Прежде всего, ясно, что для реализации этого метода потребуется всего n * m опера- ций чтения кортежей. А как в отношении операций записи кортежей? Какова кардиналь- ность результата операции соединения? (Количество операций записи кортежа будет равно кардинальности результирующего отношения, если последнее требуется записы- вать на диск.)

  • В частном, но достаточно важном случае соединения типа "многие к одному" (например, соединение типа "внешний ключ к соответствующему потенциальному ключу") кардинальность результирующего отношения почти всегда точно совпа- дает с величиной m или п в зависимости от того, какое из отношений, R или S, рас- положено на стороне "многие" рассматриваемого соединения.

  • Теперь рассмотрим более общий случай соединения типа "многие ко многим". Пусть dCR — количество различающихся значений атрибута С отношения R, по ко- торому выполняется соединение, и dCS имеет тот же смысл, но для отношения S. Если предположить, что значения атрибутов распределены равномерно (т.е. любое значение атрибута С может быть встречено с той же вероятностью, что и другие значения), то для данного кортежа отношения R существует n/dCS соответствую- щих кортежей в отношении S со значением атрибута С, равным значению этого атрибута в рассматриваемом кортеже из отношения R. Таким образом, общее ко- личество кортежей в соединении (т.е. кардинальность результирующего отноше- ния) будет равно (m * n)/dCS. Или, если повторить изложенные рассуждения, на- чав с кортежа в отношении S, кардинальность результирующего отношения соста- вит (n * m)/dCR. Эти две оценки будут различными, если dCS Ф dCR, т.е. если в отношении R существуют значения атрибута С, которые не встречаются в отноше- нии S, и наоборот. В этом случае следует использовать худшую из оценок.

Конечно, как уже отмечалось, на практике подсчитываются операции ввода-вывода страниц, а не кортежей. Поэтому предположим, что в отношениях R и S на странице по- мещается соответственно pR и pS кортежей (т.е. отношения занимают m/pR и n/pS стра- ниц соответственно). Теперь легко увидеть, что процедура, псевдокод которой показан на рис. 17.4, выполнит (m/pR) + (m*n)/pS операций чтения страниц. Аналогично, если поменять местами роли отношений R и S (отношение S считать внешним, a R — внутрен- ним), количество операций чтения страниц составит (n/pS) + (n*m) /pR.

Для примера предположим, что m = 100, п = 10 ООО, pR = 1 и pS = 10. Тогда ре- зультатами вычисления последних двух формул будут значения 100 100 и 1 001 000 операций чтения страниц соответственно.

Замечание. В описанном подходе в качестве внешнего отношения желательно ис- пользовать меньшее из двух исходных отношений (в данном случае понятие "меньшее" относится к количеству занимаемых им страниц внешней памяти).

Завершая краткое обсуждение метода последовательного просмотра, заметим, что этот прием является наихудшим из всех. В нем предполагается, что отношение S не име- ет ни индекса, ни хеш-таблицы для атрибута С, по которому выполняется соединение. Эксперименты, проведенные Биттоном (Bitton) [17.7], показали, что если предполагае-

мая ситуация (отсутствие индексов и хеш-таблиц) действительно имеет место, то методы обработки можно улучшить, построив нужный индекс или хеш-таблицу динамически и продолжив обработку запроса с помощью методов поиска по индексу или хеш-таблице (см. следующие два подраздела). Как упоминается в конце следующего раздела, эта идея поддерживается и в [17.37].

Поиск по индексу

Теперь рассмотрим ситуацию, в которой для атрибута S. С внутреннего отношения S существует индекс X (рис. 17.5). Преимущество поиска по индексу по сравнению с мето- дом последовательного просмотра состоит в том, что благодаря наличию индекса X для данного кортежа внешнего отношения R возможен переход непосредственно к соответ- ствующему кортежу внутреннего отношения S. Общее количество операций чтения кор- тежей из отношений R и S будет равно кардинальности результирующего отношения операции соединения. Общее количество операций чтения страниц для отношений R и S составит (m/pRJ + (mn/dCS) при наихудшем предположении, что каждая операция чте- ния кортежа из отношения S требует обращения к отдельной странице.

К /* Использование индекса X по атрибуту S.C */

do i := 1 to m ; /* Внешний цикл */

/* Пусть для значения индексированного атрибута R[i].C */

/* существует к вхождений индекса: Х[1], Х[к] */

do j := 1 to к ; /* Внутренний цикл */

/* Пусть S[j] — кортеж из S, на который указывает индекс X[j] */ <к результату добавить соединенный кортеж R[i] * S[j]> ; end ; end ;

зш=========:===========^^

Рис. 17.5. Поиск по индексу

Если кортежи отношения S хранятся в порядке значений соединяющего атрибута С, то количество операций чтения страницы уменьшится до значения (m/pR) + (mn/dCS)/pS. Воспользовавшись теми же пробными значениями, что и выше (т = 100, п = 10 ООО, pR = 1, pS = 10), и предположив, что dCS = 100, получим в результате вы- числения двух последних формул значения 10 100 и 200 соответственно. Разница между полученными значениями указывает, что кортежи хранимых отношений целесообразно размещать в "подходящей" физической последовательности [17.9].

Однако при оценке затрат следует учитывать и накладные расходы, связанные с вы- полнением операций чтения в самом индексе. Наихудшим является предположение, что при поиске соответствующих кортежей в отношении S для каждого кортежа в отноше- нии R потребуется выполнить "непредвиденный" поиск по индексу, требующий чтения страницы для каждого уровня индекса. Для индекса, обладающего х уровнями, операция поиска добавит к общему количеству операций чтения страницы еще т*х операций. На практике х обычно имеет значение 3 или меньше. (Более того, весьма вероятно, что верхний уровень индекса на протяжении всей обработки данных будет находиться в па- мяти, что значительно сократит количество операций чтения страниц.)

Поиск по хеш-таблице

Поиск по хеш-таблице аналогичен поиску по индексу, но в качестве "быстрого пути доступа" к значениям атрибута S.C внутреннего отношения S вместо индекса использу- ется хеш-таблица (рис. 17.6). Вывод оценки затрат, связанных с выполнением данного метода, оставлен в качестве упражнения для читателя.

/* Использование хеш-таблицы Н по атрибуту S.C */

do i := 1 to m ; /* Внешний цикл

*/

k := hash (R[i].C)

/* Пусть имеется h кортежей из S, хранимых в H[k

*/

do j := 1 to h ; /* Внутренний цикл

*/

if R[i].C = S[j].C then

<к результату добавить соединенный кортеж

R[i] * S[j]> ;

end ;

end ;

Рис, 17.6. Поиск no хеш-таблице

Метод слияния

В методе слияния предполагается, что кортежи отношений R и S хранятся во внешней памяти в последовательности значений атрибута С, по которому выполняется соедине- ние. Если данное предположение отвечает действительности, то два отношения можно будет просматривать в их физической последовательности, причем обе операции про- смотра можно синхронизировать, в результате чего соединение может быть выполнено за один проход по данным (это утверждение истинно по крайней мере для соединений типа "один ко многим", но не всегда истинно для соединений типа "многие ко многим"). Несомненно, подобный метод будет оптимальным, так как каждая страница данных счи- тывается всего один раз (рис. 17.7). Другими словами, количество операций чтения стра- ниц составит (m/pR) + {n/pS).

Из этого можно сделать следующие заключения.

  • Физическая кластеризация логически связанных данных является одним из важ- нейших факторов, влияющих на производительность системы, т.е. в высшей сте- пени желательно проводить кластеризацию данных так, чтобы они соответствова- ли соединениям, наиболее важным для предприятия [17.9].

  • Если подобная кластеризация отсутствует, то хорошей идеей может быть сорти- ровка непосредственно во время выполнения запроса какого-то одного или обоих отношений произвольным способом с последующим соединением методом слия- ния. (Безусловно, назначение подобной сортировки состоит в динамическом соз- дании требуемой кластеризации.) На этот метод обычно ссылаются, что вполне логично, как на метод сортировки-слияния [17.10].

Более подробно эта тема обсуждается в [17.35].

/* Кортежи обоих отношений, R и S, хранятся в последовательности */

/* значений атрибута С. */

/* Здесь приведен код для соединения типа "многие ко многим", */

/* пример для соединения типа "многие к одному" оставлен */

/* в качестве упражнения для читателя. */

г := 1 ; s := 1 ;

do while г < m and s < n ; /* Внешний цикл */

v := R[r].C ;

do j := s by 1 while S[j].C < v ; end ; s := j ;

do j := s by 1 while S[j].C = v ; /* Внутренний цикл */

do i := r by 1 while R[i].C = v ;

<к результату добавить соединенный кортеж R[i] * S[j]> ;

end ; end ; s := j ;

do i := r by 1 while R[i].C = v ; end ; r := i ; end ;

Рис. 17.7. Метод слияния (для соединений типа "многие ко многим")

Хеширование

Как и метод слияния, метод хеширования позволяет обойтись одним проходом для каждо- го из двух соединяемых отношений (рис. 17.8). В результате первого прохода строится хеш- таблица для отношения S по значениям атрибута S. С. Записи в этой таблице содержат значе- ние соединяемого атрибута (а также, возможно, значения других атрибутов отношения S) и указатель на соответствующий кортеж. Во время второго прохода сканируются кортежи от- ношения R и вычисляется та же хеш-функция для значений соединяемого атрибута R.C. Когда по вычисленному для кортежа отношения R значению хеш-функции в хеш-таблице обнаружи- вается один или несколько соответствующих ему кортежей отношения S, алгоритм проверяет, действительно ли равны значения R.C и S.C, и, если это так, генерируется кортеж (или корте- жи) результирующего соединения. Основным преимуществом данного метода по сравнению с методом слияния является то, что отношения R и S можно хранить в произвольной последо- вательности, а значит, не требуется предварительно сортировать.

Как и в случае метода поиска по хеш-таблице, вывод оценок затрат, связанных с ис- пользованием хеширования, оставлен в качестве упражнения для читателя.

Соседние файлы в папке Дейт К. Дж. Введение в системы баз данных [7 издание]