DeepEdit!

Программирование баз данных на Oracle, техническая документация, литература, статьи и публикации

  • Увеличить размер шрифта
  • Размер шрифта по умолчанию
  • Уменьшить размер шрифта

Группировка потока(CLUSTER)

В предыдущей версии нашей суммирующей функции мы использовали предложение ORDER, так как в этой функции предполагается, что записи для каждого из ее экземпляров упорядочены по региону. Еще один параметр, CLUSTER, гарантирует, что записи с одинаковыми значениями в указанных столбцах будут сгруппированы в пределах экземпляра функции. Однако помните, что этот параметр не вызывает сортировки значений.
В силу того, что в нашей функции рассматривается только один столбец, можно легко перейти к группировке. Для этого используется следующий синтаксис:

Проверка показывает, что вариант с параметром CLUSTER для одного столбца работает быстрее варианта с параметром ORDER.
Какой вариант выбрать?
Какой из всех этих вариантов секционирования и организации потока лучше подходит в вашем конкретном случае?
PARTITION BY ANY (произвольное секционирование)
Используйте этот вариант, если вам нужна максимальная скорость и порядок следования записей вообще не важен. Например, если
вам надо выполнить независимые вычисления для каждой записи курсора REF CURSOR, выберите данный способ, так как Oracle распределит записи, не заботясь об их порядке.
Мне еще не встречались ситуации, когда требовалось бы сочетание произвольного секционирования с параметрами ORDER или CLUSTER, но такая комбинация синтаксически допустима.
PARTITION BY RANGE (секционирование по диапазону)
Указывайте этот параметр, если ваша функция предусматривает совместную обработку определенных записей и эти записи равномерно распределены по значениям секционирования. В этом случае все экземпляры параллельной функции будут выполнять примерно равные объемы работы.
Этот тип секционирования можно сочетать с параметрами ORDER BY или CLUSTER BY. Имейте в виду, что вариант с группировкой будет работать немного быстрее.
PARTITION BY HASH (хеш-секционирование)
Используйте этот параметр, если ваша функция требует, чтобы определенные записи обрабатывались совместно, и распределение имеет некоторый перекос. Алгоритм хеширования увеличивает шансы того, что все экземпляры параллельной функции будут выполнять примерно равные объемы работы.
Допустимо комбинирование данного параметра с ORDER BY или CLUSTER BY. При этом вариант с параметром CLUSTER работает чуть быстрее.
Что делает Oracle?
У вас, наверное, уже возник вопрос, как база данных выполняет секционирование результатов запроса. Выполняет ли Oracle по одному запросу в каждом экземпляре параллельной функции или он выполняет единственный запрос и секционирует его результат? Давайте выясним это, обратившись к разделяемому пулу.


Здесь присутствуют только два курсора: один, выполненный нами, и один, выполненный в табличной функции; у обоих счетчики разборов и выполнений содержат 1. Это означает, что используется единственный курсор, а Oracle по необходимости выполняет секционирование полученных строк.
Сколько нужно PQ-серверов?
Для большинства операций с параллельными запросами можно ограничить количество (или хотя бы повлиять на него) задействованных в них PQ-серверов. Например, можно задать степень параллелизма для таблицы, и Oracle будет стремиться обеспечить требуемое количество PQ-серверов для запросов к этой таблице. Также можно задать степень параллелизма (а, следовательно, и количество используемых PQ-серверов) для любого конкретного запроса, указав соответствующие подсказки оптимизатору.
К сожалению, такие возможности отсутствуют для параллельных табличных функций.
Хотелось бы иметь возможность использовать синтаксис такого типа:

Так можно было бы задать максимальное количество PQ-серверов, используемых при одном обращении к табличной функции. Несмотря на эту легкую критику, надо признать, что Oracle достаточно хорошо справляется с задачей определения требуемого количества PQ-серверов.
Использование табличных функций
В этом разделе мы на реальном примере из практики большой кабельной компании, пытающейся отслеживать повторные наряды, покажем, как используются табличные функции. Говоря попросту, повторный наряд - это направление техника по одному и тому же адресу для повторного выполнения (или исправления) уже сделанной работы в течение 30 дней. Повторный визит не всегда связан с наличием претензий - он может быть результатом установки оборудования в 30- дневный период после предварительного заказа.
Адреса определяются предопределенными идентификаторами. Они могут соответствовать чему угодно, от конкретной кабельной розетки
до отдельного дома или большого торгового центра. Вид работы определяется идентификатором типа наряда. Например, тип 1 может означать «Прокладка кабеля», а тип 2 - «Замена кабеля».
Компания имеет отделения в нескольких регионах, в каждом из которых используется собственный набор идентификаторов адресов, типов нарядов и критериев повторного наряда. Эти критерии определяют пары типов нарядов, которые должны быть выданы по одному адресу в течение 30-дневного периода, чтобы наряд был признан повторным. Типы нарядов в такой паре могут совпадать или не совпадать, например «Ремонт кабеля», произошедший после «Прокладки кабеля», может считаться таким же повторным нарядом, как и два последовательных наряда на «Прокладку кабеля».
Эта таблица содержит определения повторных нарядов для каждого региона, включая дату их ввода в действие. Вот пример записи.
Эти критерии хранятся в таблице:
В этой записи говорится, что в регионе 1 наряд с типом 102, следующий в 30-дневный период за нарядом 44 и по тому же адресу, считается повторным.
Таблица ORDERS содержит поля, необходимые для определения «по- вторности» наряда.

Дополнительную сложность этим условиям придает то, что компания обрабатывает ежедневно десятки тысяч заявок, а также то, что критерии повторного наряда могут измениться в любой момент, поэтому новый набор данных должен быть получен быстро. Большое количество
записей в сочетании с необходимостью «поштучной» обработки записей для получения результирующего множества делает это приложение идеальным кандидатом на применение табличных функций.
Заголовок функции
Для начала разберемся, из чего состоит заголовок нашей функции.
Как это свойственно заголовкам функций, здесь можно много о чем рассказать, поэтому разберем его строка за строкой.

Строка 1
Определяет имя функции и ее параметр - курсор типа REF CURSOR со строгим контролем типа, объявленный в другом пакете, например, так:

При обращении к функции будем передавать ей оператор SELECT, возвращающий все наряды за последние 30 дней.
Строка 2
Определяет структуру возвращаемых функцией записей. Данный тип был создан с помощью следующих SQL-определений объекта и коллекции:

Строка 3
Указывает на то, что функция конвейеризирует возвращаемые строки по мере их появления.
Строка 4
Определяет, каким способом будут распределяться по нескольким параллельным экземплярам функции строки, полученные переданным ей курсором. Строки должны разделяться по значению столбца REGION_ID. Это значит, что все записи определенного региона будут обработаны одним экземпляром функции. Из этого не следует, что будет создано по одному экземпляру для каждого региона. Oracle по своему усмотрению распределит имеющиеся PQ-серве- ры для выполнения экземпляров функции. Поэтому один экземпляр может обрабатывать несколько регионов.
Строка 5
Указывает, что в каждом из экземпляров записи должны быть отсортированы по столбцам LOCATION_ID и ORDER_DATE. Простой разбор заголовка показал большинство возможностей, скрытых в табличной функции. Эта функция позволяет использовать мощь параллельных вычислений для последовательной обработки десятков тысяч записей. Более того, она позволяет указать, какие записи будут переданы каждому из экземпляров параллельной функции, благодаря чему при кодировании можно использовать некоторые допущения. Добавим к этому отсутствие необходимости дожидаться окончания обработки всех записей, чтобы вернуть результат, и - вот она, нирвана!
Но хватит проповедей! Вернемся к нашей функции.
 









jAntivirus