СТАТЬЯ
16.02.01

предыдущая часть | содержание | следующая часть

Управление последовательностями

Генератор последовательностей генерирует порядковые номера. Это полезно для автоматической генерации уникальных первичных ключей для ваших данных, а также для координирования ключей между различными строками или таблицами.

Без генератора последовательностей порядковые номера можно было бы создавать лишь программным способом. Новое значение первичного ключа можно было бы получать выбором последнего программно вычисленного значения и наращиванием его. Этот метод требует блокировки во время выполнения транзакции и заставляет одновременно работающих пользователей ожидать очередного значения первичного ключа; такое ожидание известно как СЕРИАЛИЗАЦИЯ (буквально – "выстраивание в очередь"). Если у вас есть такие программные конструкты в ваших приложениях, вы должны заменить их обращениимя к последовательностям. Последовательности устраняют сериализацию и улучшают конкурентные способности вашего приложения.

Следующие секции объясняют, как создавать, изменять и удалять последовательности с помощью команд SQL. Рекомендации по настройке ваших последовательностей приводятся, начиная со страницы 2-18.

Создание последовательностей

Создавайте последовательность с помощью команды SQL CREATE SEQUENCE. Например, следующая команда создает последовательность, используемую для генерации номеров сотрудников для столбца EMPNO таблицы EMP:

CREATE SEQUENCE emp_sequence
    INCREMENT BY 1
    START WITH 1
    NOMAXVALUE
    NOCYCLE
    CACHE 10;

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

Опция CACHE команды CREATE SEQUENCE обеспечивает предварительную генерацию нескольких номеров последовательности и поддерживает их в памяти (кэширует), так что доступ к ним ускоряется. Когда использован последний из номеров в кэше, ORACLE считывает в кэш очередную группу номеров.

Параллельный сервер ORACLE создает дополнительные эффекты для кэшируемых последовательностей; для дополнительной информации обратитесь к документу ORACLE7 Parallel Server Administrator's Guide. Общая информация о кэшировании номеров последовательностей приведена на странице 2-18.

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

Чтобы создать последовательность в своей схеме, вы должны иметь системную привилегию CREATE SEQUENCE; чтобы создать последовательность в схеме другого пользователя, вы должны иметь системную привилегию CREATE ANY SEQUENCE.

Изменение последовательностей

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

Чтобы изменить последовательность, используйте команду SQL ALTER SEQUENCE. Например, следующее предложение изменяет последовательность EMP_SEQUENCE:

ALTER SEQUENCE emp_sequence
    INCREMENT BY 10
    MAXVALUE 10000
    CYCLE
    CACHE 20;

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

Чтобы изменить последовательность, вы должны иметь ее в своей схеме, либо иметь системную привилегию ALTER ANY SEQUENCE.

Использование последовательностей

Следующие секции приводят некоторые рекомендации о том, как использовать последовательность после того, как она определена. Однажды определенная, последовательность может быть сделана доступной многим пользователям, которые могут обращаться к этой последовательности и вызывать ее приращения, не прибегая к ожиданию. ORACLE не ждет завершения транзакции, выполнившей приращение последовательности, для того чтобы осуществить очередное приращение этой последовательности.

Пример, рассматриваемый здесь и в последующих секциях, показывает, как можно применять последовательность в связях между главной и детальной таблицами. Предположим, что в систему ввода заказов входят, в частности, две таблицы – ORDERS (главная таблица) и LINE_ITEMS (детальная таблица), – содержащие информацию о заказах покупателей. Последовательность ORDER_SEQ определена следующим предложением:

CREATE SEQUENCE order_seq
    START WITH 1
    INCREMENT BY 1
    NOMAXVALUE
    NOCYCLE
    CACHE 20;

Обращение к последовательности

Обращение к последовательности осуществляется в предложениях SQL через псевдостолбцы NEXTVAL и CURRVAL; каждый новый номер данной последовательности генерируется обращением к ее псевдостолбцу NEXTVAL, тогда как текущий номер последовательности можно извлекать неоднократно путем обращения к ее псевдостолбцу CURRVAL.

NEXTVAL и CURRVAL не являются зарезервированными или ключевыми словами; их можно использовать как имена псевдостолбцов в предложениях SQL, таких как SELECT, INSERT или UPDATE.

Генерация номеров последовательности через NEXTVAL

Чтобы сгенерировать и возвратить очередной номер данной последовательности, обратитесь к seq_name.NEXTVAL, где seq_name – имя последовательности. Например, предположим, что заказчик размещает заказ. Номер последовательности можно специфицировать в списке вставляемых значений как номер нового заказа, например:

INSERT INTO orders (orderno, custno)
    VALUES (order_seq.NEXTVAL, 1032);

или в фразе SET предложения UPDATE, например:

UPDATE orders
    SET orderno = order_seq.NEXTVAL
    WHERE orderno = 10112;

или в самом внешнем списке SELECT запроса или подзапроса, например:

SELECT order_seq.NEXTVAL FROM dual;

По определению, первое обращение к ORDER_SEQ.NEXTVAL возвратит значение 1. Каждое последующее предложение, обращающееся к ORDER_SEQ.NEXTVAL, возвратит очередной номер данной последовательтности (2, 3, 4 и т.д.). Псевдостолбец NEXTVAL может генерировать столько новых номеров последовательности, сколько потребуется. Однако на одно предложение генерируется лишь один новый номер; иными словами, если в данном предложении SQL псевдостолбец NEXTVAL встречается несколько раз, то лишь для первого обращения будет возвращен новый номер последовательности, а все остальные обращения в этом предложении возвратят тот же самый номер. После того как очередной номер последовательности сгенерирован, этот номер доступен лишь сессии, сгенерировавшей его. Независимо от подтверждения или отката транзакций, все пользователи, обращающиеся к ORDER_SEQ.NEXTVAL, получают уникальные значения. Поэтому, если несколько пользователей одновременно обращаются к одной и той же последовательности, каждый из них может получать номера этой последовательности с промежутками, потому что номера генерируются также другими пользователями.

Использование номеров последовательности через CURRVAL

Чтобы обратиться к текущему значению номера последовательности, которое уже было сгенерировано для вашей сессии, используйте обозначение seq_name.CURRVAL, где seq_name – имя последовательности. Псевдостолбец CURRVAL может использоваться лишь в том случае, если в текущей сессии уже было выдано обращение к seq_name.NEXTVAL для данной последовательности (не обязательно в текущей транзакции). CURRVAL можно использовать сколько угодно раз, в том числе несколько раз в одном и том же предложении. Очередной номер последовательности не будет сгенерирован, пока не будет выполнено очередное обращение к NEXTVAL. Продолжая предыдущий пример, вы могли бы завершить размещение заказа, вставив в детальную таблицу строки элементов заказа:

INSERT INTO line_items (orderno, partno, quantity)
    VALUES (order_seq.CURRVAL, 20321, 3);

INSERT INTO line_items (orderno, partno, quantity)
     VALUES (order_seq.CURRVAL, 29374, 1);

Если предложение INSERT в предыдущей секции сгенерировало для номера нового заказа, скажем, число 347, то оба эти предложения вставят строки с тем же номером заказа 347.

Применения и ограничения NEXTVAL и CURRVAL

NEXTVAL и CURRVAL могут использоваться в следующих местах:

NEXTVAL и CURRVAL не могут использоваться в следующих местах:

Кэширование номеров последовательностей

Номера последовательностей могут поддерживаться в кэше последовательностей в глобальной области системы (SGA). Номера последовательностей извлекаются из кэша быстрее, чем при считывании их с диска.

Кэш последовательностей состоит из входов. Каждый вход может содержать много номеров для одной последовательности.

Чтобы организовать эффективный доступ ко всем номерам последовательностей, соблюдайте следующие рекомендации:

Число входов в кэше последовательностей

Когда приложение обращается к последовательности, находящейся в кэше последовательностей, оно быстро получает номера этой последовательности. Однако, когда приложение обращается к последовательности, которая не находится в кэше, такая последовательность должна быть считана с диска в кэш, прежде чем ее номера могут быть использованы.

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

Число входов в кэше последовательностей определяется параметром инициализации SEQUENCE_CACHE_ENTRIES. Умалчиваемое значение этого параметра составляет 10 входов. Помимо ваших последовательностей, ORACLE внутренне создает и использует последовательности для таких целей, как аудитинг, гранты системных и объектных привилегий, профили, отладка хранимых процедур, а также метки. При задании числа входов в кэше последовательностей вы должны учитывать эти дополнительные последовательности.

Если значение SEQUENCE_CACHE_ENTRIES слишком мало, ORACLE может пропускать номера последовательностей, как в следующем сценарии: допустим, вы используете четыре кэшируемых последовательности, и SEQUENCE_CACHE_ENTRIES = 4, т.е. кэш заполнен. Если вы создадите пятую последовательность, то она заменит наиболее давно использовавшуюся последовательность в кэше. Все остававшиеся в кэше значения этой вытесненной последовательности будут потеряны. Например, если вытесняемая последовательность первоначально имела в кэше 10 значений, из которых было использовано лишь одно, то будут потеряны 9 значений этой последовательности.

Число значений в каждом входе кэша последовательностей

Когда последовательность считывается в кэш последовательностей, номера этой последовательности генерируются и помещаются во вход кэша. Отсюда эти номера могут быть быстро извлечены. Количество значений последовательности, сохраняемых в кэше, определяется параметром CACHE в предложении CREATE SEQUENCE. Умалчиваемое значение этого параметра равно 20.

Следующее предложение CREATE SEQUENCE создает последовательность SEQ2, для которого в кэше последовательностей будут поддерживаться 50 значений:

CREATE SEQUENCE seq2
     CACHE 50

После этого первые 50 значений SEQ2 будут выбираться из кэша. При обращении к 51-му значению последовательности с диска в кэш будут считаны очередные 50 значений.

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

Если вы в предложении CREATE SEQUENCE используете опцию NOCACHE, то значения этой последовательности не кэшируются. В этом случае каждое обращение к последовательности требует чтения с диска, что замедляет доступ к последовательности. Следующее предложение CREATE SEQUENCE создает последовательность SEQ3, значения которого не поддерживаются в кэше последовательностей:

CREATE SEQUENCE seq2
     NOCACHE

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

Чтобы использовать последовательность, вы должны либо владеть ею в своей схеме, либо иметь объектную привилегию SELECT для последовательности, принадлежащей другому пользователю.

Удаление последовательностей

Если последовательность больше не нужна, вы можете удалить ее с помощью команды SQL DROP SEQUENCE. Например, следующее предложение удаляет последовательность ORDER_SEQ:

DROP SEQUENCE order_seq;

При удалении последовательности ее определение удаляется из словаря данных. Все синонимы для последовательности остаются, но возвращают ошибку при обращении к ним.

Привилегии, требуемые для удаления последовательностей

Вы можете удалять любую последовательность, содержащуюся в вашей схеме. Чтобы удалить последовательность в схеме другого пользователя, вы должны иметь системную привилегию DROP ANY SEQUENCE.

Управление синонимами

Синоним – это алиас для таблицы, обзора, снимка, последовательности, процедуры, функции или пакета. Следующие секции объясняют, как создавать, использовать и удалять синонимы с помощью команд SQL.

Создание синонимов

Создавайте синоним с помощью команды SQL CREATE SYNONYM. Например, следующее предложение создает общий синоним с именем PUBLIC_EMP по таблице EMP, содержащейся в схеме пользователя JWARD:

CREATE PUBLIC SYNONYM public_emp FOR jward.emp;

Привилегии, требуемые для создания синонимов

Чтобы создать личный синоним в своей схеме, вы должны иметь привилегию CREATE SYNONYM; чтобы создать личный синоним в схеме другого пользователя, вы должны иметь системную привилегию CREATE ANY SYNONYM. Чтобы создать общий синоним, вы должны иметь системную привилегию CREATE PUBLIC SYNONYM.

Использование синонимов

К синониму можно обращаться в предложении SQL так же, как к нижележащему объекту этого синонима. Например, если синоним с именем EMP ссылается на таблицу или обзор, то следующее предложение законно:

INSERT INTO emp (empno, ename, job)
     VALUES (emp_sequence.NEXTVAL, 'SMITH', 'CLERK');

Если синоним с именем FIRE_EMP ссылается на независимую процедуру или пакетированную процедуру, то он может использоваться в следующем контексте:

EXECUTE fire_emp(7344);

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

Вы можете с успехом использовать любой личный синоним, содержащийся в вашей схеме, а также любой общий синоним, при условии, что вы имеете необходимые привилегии для доступа к нижележащему объекту, полученные либо явно, либо через действующую роль, либо через группу PUBLIC. Вы можете также обращаться к любому личному синониму, содержащемуся в чужой схеме, если вам были назначены необходимые объектные привилегии для этого личного синонима. Вы можете использовать личный синоним другого пользователя лишь согласно тем объектным привилегиям, которые были вами получены. Например, если у вас есть привилегия SELECT для синонима JWARD.EMP, то вы можете выдавать запросы по синониму JWARD.EMP, но не можете, скажем, вставлять строки через этот синоним.

Удаление синонимов

Чтобы удалить ненужный синоним, используйте команду SQL DROP SYNONYM. При удалении личного синонима опустите ключевое слово PUBLIC; при удалении общего синонима укажите ключевое слово PUBLIC. Например, следующее предложение удаляет личный синоним с именем EMP:

DROP SYNONYM emp;

Следующее предложение удаляет общий синоним с именем PUBLIC_EMP:

DROP PUBLIC SYNONYM public_emp;

Когда вы удаляете синоним, его определение удаляется из словаря данных. Все объекты, ссылающиеся на удаленный синоним, остаются, но становятся недействительными.

Привилегии, требуемые для удаления синонимов

Вы можете удалить любой личный синоним, содержащийся в вашей схеме. Чтобы удалить личный синоним в схеме другого пользователя, вы должны иметь системную привилегию DROP ANY SYNONYM. Чтобы удалить общий синоним, вы должны иметь системную привилегию DROP PUBLIC SYNONYM.

Управление индексами

Индексы используются в ORACLE для того, чтобы обеспечивать быстрый доступ к строкам таблицы. Индексы ускоряют доступ к данным для операций, затрагивающих небольшую часть строк таблицы.

ORACLE не ограничивает количество индексов, которые вы можете создавать по таблице. Однако вы должны рассматривать возможные выгоды в производительности и потребности ваших приложений базы данных, когда определяете, какие столбцы индексировать.

Следующие секции объясняют, как создавать, изменять и удалять индексы с помощью команд SQL, и предоставляют некоторые простые рекомендации по работе с индексами. Соображения о том, как влияет создание индексов на производительность, приводятся в секции "Как использовать индексы" на странице 5-2.

Создавайте индексы после загрузки данных в таблицу

За одним заслуживающим упоминания исключением, вы должны создавать индекс по таблице после того, как данные были вставлены или загружены в таблицу (с помощью SQL*Loader или импорта). Гораздо эффективнее вставить строки данных в таблицу, не имеющую индексов, а затем создать индексы для последующего доступа к этим данным. Если вы создадите индексы перед тем, как загружать данные в таблицу, то при вставке каждой строки данных требуется обновление всех индексов. Исключение из этого правила касается кластера, для которого вы ДОЛЖНЫ создать индекс перед тем, как вставлять в кластер любые данные.

Когда индекс создается по таблице, уже имеющей данные, ORACLE должен использовать область сортировки, чтобы создать индекс. ORACLE использует область сортировки в памяти, распределяемой для создателя индекса (размер этой области на пользователя определяется параметром инициализации SORT_AREA_SIZE), но вынужден также обмениваться информацией сортировки с временными сегментами, распределяемыми от имени процесса создания индекса. Если индекс исключительно велик, может оказаться полезным выполнить следующие шаги:

  1. Создать новое табличное пространство для временных сегментов, используя команду CREATE TABLE.
  2. С помощью опции TEMPORARY TABLESPACE команды ALTER USER изменить табличное пространство для временных сегментов для создателя индекса, указав вновь созданное табличное пространство.
  3. Создать индекс, используя команду CREATE INDEX.
  4. С помощью команды DROP TABLESPACE удалить табличное пространство для временных сегментов. Затем командой ALTER USER снова переопределить табличное пространство для временных сегментов для создателя индекса, указав старое табличное пространство.

При некоторых условиях, можно загрузить данные в таблицу, используя режим SQL*Loader "загрузки по прямому маршруту", и создать индекс по мере загрузки данных; для дополнительной информации обратитесь к документу ORACLE7 Server Utilities User's Guide.

Индексируйте корректные таблицы и столбцы

Используйте следующие рекомендации, принимая решение о создании индекса:

этот процент; чем больше сгруппированы строки по значениям индексов, тем выше этот процент.

Некоторые столбцы являются сильными кандидатами на индексирование. Таковы столбцы, имеющие одну или несколько из следующих характеристик:

Столбцы, обладающие следующими характеристиками, меньше подходят для индексирования:

Столбцы LONG и LONG RAW не могут быть индексированы.

Размер одной записи индекса не может превышать приблизительно одной трети размера блока данных. Проконсультируйтесь с администратором базы данных, чтобы определить память, потребную для создаваемого индекса.

Ограничивайте число индексов на таблицу

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

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

Упорядочивайте столбцы индекса для производительности

Порядок, в котором столбцы инлекса перечисляются в команде CREATE INDEX, не обязан соответствовать порядку, в котором эти столбцы определены в таблице. Однако порядок столбцов в команде CREATE INDEX существенен, так как он может повлиять на производительность запросов. В общем случае, вы должны первым в индексе указывать тот столбец, который будет использоваться наиболее часто.

Например, предположим, что таблица VENDOR_PARTS имеет следующие столбцы:

Рис.2-1
Таблица VENDOR_PARTS
VEND_ID
(поставщик)

1012
1012
1012
1010
1010
1220
1012
1292
PART_NO
(изделие)
10-440
10-441
457
10-440
457
08-300
08-300
457
UNIT_COST
(цена единицы)
.25
.39
апр.95
.27
05.окт
янв.33
янв.19
май.28

Предположим, что существуют пять поставщиков, и каждый поставщик выпускает около 1000 изделий.

Допустим, таблица VENDOR_PARTS обычно опрашивается предложениями SQL, подобными следующему:

SELECT * FROM vendor_parts
     WHERE part_no = 457 AND vendor_id = 1012;

Чтобы увеличить производительность таких запросов, вам следует создать составной индекс, указав первым самый селективный столбец, т.е. столбец, имеющий БОЛЬШЕ различных значений:

CREATE INDEX ind_vendor_id
     ON vendor_parts (part_no, vendor_id);

Индексы ускоряют извлечение для любого запроса, в котором участвует ВЕДУЩАЯ ЧАСТЬ индекса. Так, в приведенном выше примере, запросы, в которых фраза WHERE использует только столбец PART_NO, также получат выигрыш производительности. Поскольку столбец VENDOR_ID имеет лишь пять различных значений, создание отдельного индекса по этому столбцу не имеет смысла.

Создание индексов

Индекс может быть создан для таблицы, чтобы улучшить производительность запросов, выдаваемых по соответствующей таблице. Индекс может также быть создан для кластера. Вы можете создать СОСТАВНОЙ индекс по нескольким (до 16) столбцам.

ORACLE вводит в действие ограничение целостности UNIQUE или PRIMARY KEY, автоматически создавая уникальный индекс по уникальному или первичному ключу. В общем случае, для обеспечения уникальности предпочтительнее создавать ограничения, чем использовать устаревший синтаксис CREATE UNIQUE INDEX.

Индексы создаются с помощью команды SQL CREATE INDEX. Например, следующее предложение создает индекс с именем EMP_ENAME для столбца ENAME таблицы EMP:

CREATE INDEX emp_ename ON emp(ename)
    TABLESPACE users
    STORAGE (INITIAL 20K
                        NEXT 20K
                        PCTINCREASE 75)
    PCTFREE 0;

Заметьте, что для этого индекса явно специфицировано несколько параметров памяти.

Привилегии, требуемые для создания индексов

Чтобы создать новый индекс, вы должны владеть соответствующей таблицей или иметь для нее объектную привилегию INDEX. Схема, в которой создается индекс, должна также иметь квоту для табличного пространства, в котором будет содержаться индекс, либо системную привилегию UNLIMITED TABLESPACE. Чтобы создать индекс в схеме другого пользователя, вы должны иметь системную привилегию CREATE ANY INDEX.

Удаление индексов

Вы можете захотеть удалить индекс по любой из следующих причин:

Когда вы удаляете индекс, все экстенты его сегмента возвращаются в содержащее табличное пространство и становятся доступными для других объектов в этом табличном пространстве.

Для удаления индекса используйте команду SQL DROP INDEX. Например, следующее предложение удаляет индекс EMP_ENAME:

Когда вы удаляете таблицу, все ассоциированные индексы удаляются автоматически.

Привилегии, требуемые для удаления индекса

Чтобы удалить индекс, вы должны либо иметь его в своей схеме, либо обладать системной привилегией DROP ANY INDEX.

Управление кластерами, кластеризованными таблицами и индексами кластеров

Так как кластеры хранят взаимосвязанные строки разных таблиц вместе в одних и тех же блоках данных, при правильном использовании кластеров достигаются два основных преимущества:

Указания по созданию кластеров

Следующие секции приводят некоторые рекомендации по созданию кластеров. Относительно характеристик производительности обратитесь к секции "Как использовать кластеры" на странице 5-8.

Выбирайте подходящие таблицы для кластера

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

Выбирайте подходящие столбцы для ключа кластера

Тщательно выбирайте столбцы для ключа кластера. Если в запросах, выполняющих соединение таблиц, используются несколько общих столбцов, сделайте ключ кластера составным ключом. В общем, характеристики, которые указывают на хороший ключ кластера, те же, что и для любого индекса; см. секцию "Индексируйте корректные таблицы и столбцы" на странице 2-22.

Хороший ключ кластера имеет достаточно уникальных значений, так что группа строк, соответствующих каждому значению ключа, заполняет приблизительно один блок данных. Слишком малое число строк на значение ключа кластера приводит к расходу памяти и мало дает для улучшения производительности. Ключи кластера столь специфичны, что слишком малое количество строк, имеющих одинаковое значение ключа, дает большой процент неиспользуемой памяти в блоках, если только при создании кластера не было специфицировано маленькое значение SIZE.

Слишком большое число строк на значение ключа кластера может привести к лишним просмотрам при отыскании строк для данного ключа. Ключи кластера, созданные по слишком общим атрибутам (таким, как пол: МУЖ или ЖЕН), приводят к избыточным поискам и могут дать ухудшение производительности вместо улучшения.

Индекс кластера не может быть уникальным, и не может включать столбец, определенный с типом данных LONG.

Соображения производительности

Необходимо заметить, что кластеры могут ухудшить производительность предложений DML (INSERT, UPDATE и DELETE) по сравнению с хранением таблицы вне кластера со своим собственным индексом. Это объясняется способом использования памяти, а также количеством блоков, которые должны быть посещены при просмотре таблицы; поскольку в каждом блоке кластера сосредоточены данные нескольких таблиц, каждая отдельная таблица в кластере занимает больше блоков, чем если бы она хранилась вне кластера. Вы должны принимать ваши решения относительно кластеров, имея в виду эти компромиссы.

Чтобы идентифицировать данные, которые лучше было бы хранить в кластеризованной форме, чем в некластеризованной, поищите таблицы, связанные друг с другом через ограничения ссылочной целостности, а также таблицы, которые часто опрашиваются совместно, с помощью предложений SELECT, соединяющих данные из двух или более таблиц. Путем кластеризации таких таблиц по столбцам, используемым для соединения данных, вы уменьшите число блоков данных, которое должно быть обработано для выполнения запросов; все строки, необходимые для соединения по данному значению ключа кластера, находятся в одном и том же блоке. Поэтому производительность запросов для соединений улучшается. Аналогично, может оказаться полезным кластеризовать единственную таблицу. Например, таблицу EMP можно было бы кластеризовать по столбцу DEPTNO, чтобы сгруппировать вместе все строки с одинаковыми значениями номера отдела. Это оказалось бы выгодным для тех приложений, которые обрабатывают таблицу EMP по отделам.

Как и индексы, кластеры не влияют на проектирование приложений. Существование кластера прозрачно для пользователей и приложений. Данные, хранящиеся в кластере, обрабатываются с помощью тех же предложений SQL, что и данные, хранящиеся в некластеризованных таблицах.

Создание кластеров, кластеризованных таблиц и индексов кластеров

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

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

Для создания кластера используйте команду SQL CREATE CLUSTER. Например, следующее предложение создает кластер с именеи EMP_DEPT, который будет содержать таблицы EMP и DEPT, кластеризуемые по (общему) столбцу DEPTNO:

CREATE CLUSTER emp_dept (deptno NUMBER(3))
     PCTUSED 80
     PCTFREE 5;

Для создания таблицы в кластере используйте команду SQL CREATE TABLE с опцией CLUSTER. Например, таблицы EMP и DEPT могут быть созданы в кластере EMP_DEPT с помощью следующих предложений:

CREATE TABLE dept (
    deptno NUMBER(3) PRIMARY KEY,
    . . . );
    CLUSTER emp_dept (deptno);

CREATE TABLE emp (
    empno NUMBER(5) PRIMARY KEY,
    ename VARCHAR2(15) NOT NULL,
    . . .);
    deptno NUMBER(3) REFERENCES dept)
    CLUSTER emp_dept (deptno);

Вы можете специфицировать в предложении CREATE TABLE схему для кластеризуемой таблицы; кластеризованная таблица не обязана быть в той же самой схеме, в которой содержится кластер.

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

CREATE INDEX emp_dept_index ON CLUSTER emp_dept INITRANS 2 MAXTRANS 5 PCTFREE 5;

Замечание: Ключ кластера не может быть уникальным. Более того, ORACLE не гарантирует уникальности отдельных столбцов ключа кластера, даже если они определены с ограничениями UNIQUE или PRIMARY KEY.

Ключ кластера устанавливает отношение между таблицами в кластере.

Привилегии, требуемые для создания кластера,

кластеризованной таблицы и индекса кластера

Чтобы создать кластер в своей схеме, вы должны иметь системную привилегию CREATE CLUSTER, а также квоту для табличного пространства, в котором будет содержаться кластер, либо системную привилегию UNLIMITED TABLESPACE. Чтобы создать кластер в схеме другого пользователя, вы должны иметь системную привилегию CREATE ANY CLUSTER, а владелец должен иметь квоту для табличного пространства, в котором будет содержаться кластер, либо системную привилегию UNLIMITED TABLESPACE.

Чтобы создать таблицу в кластере, вы должны иметь системную привилегию CREATE TABLE или CREATE ANY TABLE. Вам не требуется иметь квоту табличного пространства или системную привилегию UNLIMITED TABLESPACE для создания кластеризованной таблицы.

Чтобы создать индекс кластера, ваша схема должна содержать этот кластер, и вы должны иметь следующие привилегии:

Распределение памяти для кластера вручную

ORACLE динамически распределяет дополнительные экстенты для сегмента данных кластера при необходимости. Однако вы можете захотеть явно распределить для кластера дополнительный экстент. Например, в среде параллельного сервера ORACLE экстент кластера может быть явно распределен для конкретной инстанции.

Новый экстент можно распределить для кластера с помощью команды SQL ALTER CLUSTER с опцией ALLOCATE EXTENT. Для дополнительной информации об этом параметре команды ALTER CLUSTER обратитесь к документу ORACLE7 Parallel Server Administrator's Guide.

Удаление кластеров, кластеризованных таблиц и индексов кластеров

Кластер может быть удален, если таблицы в кластере больше не нужны. При удалении кластера удаляются все таблицы в кластере и соответствующий индекс кластера; все экстенты, принадлежавшие как сегменту данных, так и сегменту индекса кластера, возвращаются в содержащее табличное пространство и становятся доступными для других объектов в этом табличном пространстве.

Кластеризованные таблицы можно удалять индивидуально, что не затрагивает кластер, другие кластеризованные таблицы или индекс кластера. Кластеризованная таблица удаляется так же, как и некластеризованная таблица – командой SQL DROP TABLE. Обратитесь к секции "Удаление таблиц" на странице 2-8 для информации об удалении индивидуальных таблиц.

Замечание: Когда вы удаляете из кластера одиночную таблицу, ORACLE удаляет каждую строку этой таблицы индивидуально. Если вы намереваетесь удалить весь кластер, для максимизации эффективности используйте команду DROP CLUSTER с опцией INCLUDING TABLES. Удаляйте из кластера индивидуальную таблицу (с помощью команды DROP TABLE) лишь в том случае, если вы хотите оставить остальную часть кластера.

Можно удалить индекс кластера, не затрагивая сам кластер и его таблицы. Однако, кластеризованные таблицы не могут использоваться, пока не существует индекс кластера; вы должны пересоздать индекс кластера, чтобы открыть доступ к кластеру. Индексы кластера иногда приходится удалять как часть процедуры пересоздания фрагментированного индекса кластера. См. "Удаление индексов" на странице 2-25 для дополнительной информации об удалении индексов.

Чтобы удалить кластер, не содержащий таблиц, вместе с его индексом, используйте команду SQL DROP CLUSTER. Например, следующее предложение удаляет пустой кластер с именем EMP_DEPT:

DROP CLUSTER emp_dept;

Если кластер содержит одну или несколько кластеризованных таблиц, и вы намереваетесь удалить кластер вместе с таблицами, добавьте в команду DROP CLUSTER опцию INCLUDING TABLES, например:

DROP CLUSTER emp_dept INCLUDING TABLES;

Если опция INCLUDING TABLES опущена, а кластер содержит таблицы, то будет возвращена ошибка.

Если одна или несколько таблиц в кластере содержат первичные или уникальные ключи, на которые ссылаются ограничения FOREIGN KEY таблиц, находящихся вне кластера, то этот кластер нельзя удалить, не удаляя одновременно зависимых ограничений FOREIGN KEY. Это легко сделать, используя в команде DROP CLUSTER опцию CASCADE CONSTRAINTS. Например:

DROP CLUSTER emp_dept INCLUDING TABLES CASCADE CONSTRAINTS;

ORACLE возвратит ошибку, если вы не используете опцию CASCADE CONSTRAINTS и существуют зависимые ограничения.

Привилегии, требуемые для удаления кластера

Чтобы удалить кластер, вы должны иметь его в своей схеме, либо владеть системной привилегией DROP ANY CLUSTER. Вы не обязаны иметь дополнительных привилегий для удаления кластера, содержащего таблицы, даже если кластеризованные таблицы не принадлежат владельцу этого кластера.

предыдущая часть | содержание | следующая часть

Отправить ссылку на страницу по e-mail
Обсудить на форуме Oracle


Interface Ltd.
Тel/Fax: +7(095) 105-0049 (многоканальный)
Отправить E-Mail
http://www.interface.ru
Ваши замечания и предложения отправляйте автору
По техническим вопросам обращайтесь к вебмастеру
Документ опубликован: 16.02.01