Одновременное создание индексов в Firebird 5
В настоящее время при построении индекса любые изменения данных таблицы запрещены. Это необходимо для создания корректного индекса, чтобы не пропустить новые ключи, вставленные во время построения.
Алгоритм конкурентного построения индекса позволяет значительно сократить время, в течение которого требуется такая блокировка чтения. Хотя он не полностью устраняет необходимость блокировки конкурентных изменений данных таблицы, время такой блокировки значительно меньше по сравнению с традиционным неконкурентным алгоритмом. Это особенно полезно в производственной среде, где блокировка активности пользователей на длительные периоды непрактична или невозможна.
Из-за конкурентной нагрузки и дополнительной сложности конкурентное создание индекса может занять больше времени, чем традиционный подход.
Синтаксис
Новое необязательное нерезервированное ключевое слово CONCURRENTLY используется для указания конкурентного создания индекса.
Создание нового индекса
CREATE [UNIQUE] [ASC[ENDING] | DESC[ENDING]] INDEX indexname ON tablename {(col [, col ...]) | COMPUTED BY ()} [WHERE ] [CONCURRENTLY]
Активация существующего индекса
ALTER INDEX indexname {ACTIVE | INACTIVE} [CONCURRENTLY]
Обратите внимание, что CONCURRENTLY можно использовать только с ACTIVE.
Проверка уникальности
Проверить уникальность индекса при конкурентном построении сложно или невозможно. Поэтому, когда уникальный индекс создается (или активируется) конкурентно, он немедленно помечается как NOT VALIDATED в системном каталоге. Уникальность индекса проверяется после завершения построения индекса, когда индекс содержит ключи для всех записей таблицы.
Если проверка уникальности прошла успешно, метка NOT VALIDATED снимается.
Если проверка уникальности не удалась, индекс остается активным и помечается как NOT VALIDATED. Позже пользователь может найти и исправить дубликаты и снова проверить уникальность или удалить индекс, если это уместно.
Обратите внимание, что уникальный индекс с меткой NOT VALIDATED по-прежнему не позволяет вводить дубликаты в таблицу.
Для проверки уникального индекса выполните:
ALTER INDEX indexname VALIDATE UNIQUE
Эта инструкция выполняет сканирование индекса для поиска дублирующихся ключей и проверяет соответствующие записи. Если дубликаты не найдены, метка NOT VALIDATED снимается, и индекс считается проверенным. В противном случае метка NOT VALIDATED остается, и индекс можно проверить снова позже.
Команда isql SHOW INDEX теперь показывает метку NOT VALIDATED, если она присутствует.
Ограничения таблицы
Конкурентное создание индексов для ограничений таблицы, таких как PRIMARY|UNIQUE|FOREIGN KEY, пока не поддерживается. В будущем возможно поддержать PRIMARY|UNIQUE KEY, но маловероятно для FOREIGN KEY.
Примеры
Подготовьте таблицу с некоторыми данными
create table tab ( id int not null, f1 varchar(64));
insert into tab values (1, '1');
insert into tab values (1, '2');commit;
создайте индекс с использованием предложения CONCURRENTLY
create index idx_tab_f1 on tab(f1) concurrently;
создайте уникальный индекс на столбце с дубликатами
create unique index idx_tab_id on tab(id);
это вызовет ошибку:
Statement failed, SQLSTATE = 23000
attempt to store duplicate value (visible to active transactions) in unique index "IDX_TAB_ID"
-Problematic key value is ("ID" = 1)
создайте тот же уникальный индекс с использованием CONCURRENTLY
create unique index idx_tab_id on tab(id) concurrently;
это выдаст предупреждение:
Validation of unique index "IDX_TAB_ID" failed.
-attempt to store duplicate value (visible to active transactions) in unique index "IDX_TAB_ID"
-Problematic key value is ("ID" = 1)
проверьте, существует ли индекс:
show index idx_tab_id;
IDX_TAB_ID UNIQUE NOT VALIDATED INDEX ON (ID)
обратите внимание на метку NOT VALIDATED.
Проверьте индекс:
alter index idx_tab_id validate unique;
Statement failed, SQLSTATE = 23000
unsuccessful metadata update-Validation of unique index "IDX_TAB_ID" failed.
-attempt to store duplicate value (visible to active transactions) in unique index "IDX_TAB_ID"
-Problematic key value is ("ID" = 1)
Исправьте дублирующуюся запись и проверьте снова
update tab set id = 2 where f1 = '2';
commit;
alter index idx_tab_id validate unique;
ошибки нет.
Проверьте состояние индекса:
show index idx_tab_id;
IDX_TAB_ID UNIQUE INDEX ON (ID)
Скачайте HQbird и попробуйте прямо сейчас: /ru/download-hqbird