Ускорьте текстовую индексацию Oracle или позвольте индексатору работать только над низким временем загрузки

Мы используем текст Oracle индекс CTXSYS.CONTEXT для индексации приблизительно полумиллиона строк, содержащих метаинформацию. Информация распространена по двум таблицам, которые объединены процедурой, что индексатор заходит во время выполнения (функциональный индекс).

Когда я выполняю CREATE INDEX на своей локальной машине (простой dualcore ноутбук), индекс встроен приблизительно 3 минуты. На нашем сервере БД, который работает на Солярисе с 8 ядрами и 16G RAM, abozt требуются 24 часа для создания индекса для того же (точно то же) данные.

Пример кода: Это - наш индексный фидер для двух таблиц и 3 столбца:

create or replace procedure docmeta_revisions_text_feeder 
    ( p_rowid in rowid , p_clob in out nocopy clob) as v_clob CLOB begin
    FOR c1 IN (select DM.DID, DM.XDESCRIB || ' ' || DM.XAUTHOR AS data
        from DOCMETA DM
        WHERE ROWID = p_rowid) 
    LOOP
        v_clob := v_clob || c1.data;
        FOR c2 IN (
            SELECT ' ' || RV.DDOCTITLE AS data
            FROM   REVISIONS RV
            WHERE  RV.DID = c1.DID)
        LOOP
            v_clob := v_clob || c2.data;
        END LOOP;
    END LOOP;
    p_clob := v_clob;    
    end docmeta_revisions_text_feeder

Это предпочтения

BEGIN
CTX_DDL.CREATE_PREFERENCE ('concat_DM_RV_DS', 'USER_DATASTORE');
CTX_DDL.SET_ATTRIBUTE ('concat_DM_RV_DS', 'PROCEDURE',
'docmeta_revisions_text_feeder');
 END;

Теперь мы создаем индекс

CREATE INDEX concat_DM_RV_idx ON DOCMETA (FULLTEXTIDX_DUMMY)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('datastore concat_DM_RV_DS 
section group CTXSYS.AUTO_SECTION_GROUP
') PARALLEL 4;

Данные главным образом состоят из простого заголовка или имени автора + краткое описание с <1k текст.

Я пытался играть немного с включенными настройками памяти и ПАРАЛЛЕЛЬНЫМ параметром, но иметь не любой успех. Таким образом, здесь прибывший мои вопросы:

  • существует ли способ приостановить и возобновить процесс индексации (у меня есть роль CTX_SYS под рукой)?
  • у кого-либо есть подсказка, какой параметр можно было настроить (особенно емкость памяти)?
  • действительно ли возможно экспортировать и импортировать текстовый индекс?-> затем я мог выполнить индексацию на своей локальной машине и просто скопировать ее в наш сервер
  • индексатор может работать с "более низким приоритетом"?
  • возможно, что индексатор был нарушен путем блокировки операций (это - машина подготовки что доступ других параллельно). Существует ли способ заблокировать включенные таблицы, создать индекс и разблокировать их впоследствии?
12
задан Stefan 21 July 2010 в 11:51
поделиться

1 ответ

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

CREATE INDEX concat_DM_RV_idx ON DOCMETA (FULLTEXTIDX_DUMMY)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS ('datastore concat_DM_RV_DS section group CTXSYS.AUTO_SECTION_GROUP
NOPOPULATE
');

видите параметр NOPOPULATE? это сообщает индексатору, что он не должен запускать процесс заполнения / индексации. Если вы используете 11g, теперь у вас есть очень хорошая функция CTX_DDL, которая заполняет индекс по желанию, а именно процедура «POPULATE_PENDING». Вызов его по имени индекса приведет к заполнению таблицы CTXSYS, содержащей строки, которые были изменены и, следовательно, не синхронизированы. Обратите внимание, что после вызова этого метода индексатор по-прежнему ничего не запускал. Начиная с 10g (?) Соответствующая процедура CTX_DDL.SYNC_INDEX имеет несколько дополнительных параметров, например параметр "maxtime". Задайте для него, скажем, 4H, и ваш индексатор начнет синхронизировать ожидающие строки примерно в течение 4 часов. Вы повторяете эту процедуру по расписанию и готово.

К сожалению, в 9i это не работает. Итак, мы успешно попытались «смоделировать» процесс Oracle POPULATE_PENDING. Единственное ограничение для этого метода: вам нужен какой-то уникальный идентификатор строки, чтобы иметь возможность запрашивать фрагменты одного и того же содержимого из вашей таблицы. Вот что мы сделали:

1.) Создайте индекс с NOPOPULATE (см. Выше) 2.) Станьте SYS / DBA / CTXSYS (да, для этого вы можете позвонить своему администратору). Узнайте идентификатор, который имеет ваш только что созданный индекс, запросив мета-таблицу индекса:

SELECT IDX_ID FROM CTXSYS.CTX_INDEXES WHERE IDX_NAME ='concat_DM_RV_idx';

3.) Обратите внимание на полученный идентификатор индекса на желтом фрагменте бумаги и выполните этот оператор вставки как роль CTXSYS и замените <> на ваш идентификатор индекса и <> с именем таблицы, на которой построен индекс.Уникальным идентификатором строки может быть какой-то идентификатор документа или любой счетный оператор, который создает уникальный фрагмент данных вашей таблицы:

INSERT INTO CTXSYS.DR$PENDING (PND_CID,PND_PID,PND_ROWID,PND_TIMESTAMP)
SELECT <<your index id>>, 0, <<basetable name>>.ROWID, CURRENT_DATE
FROM gsms.DOCMETA
WHERE <<basetable unique row identifier>> < 50000;
COMMIT; -- Dont forget the COMMIT! DONT FORGET IT!!! WE MEAN IT!

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

4.) Теперь мы настроены на то, чтобы позволить индексатору расслабиться.

CALL CTX_DDL.SYNC_INDEX(
  'CONCAT_DM_RV_IDX', -- your index name here
  '100M', -- memory count
  NULL, -- param for partitioned idxes
  2 -- parallel count
);

запустит процесс индексации для любого количества строк, которое вы вставили на шаге 3.) Чтобы запустить следующий фрагмент, повторите шаг 3) со следующими 50 000 или около того строк («где id от 50 000 до 100 000»)

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

CALL CTX_DDL.OPTIMIZE_INDEX('CONCAT_DM_RV_IDX', 'REBUILD');

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

SELECT CTX_REPORT.INDEX_SIZE('CONCAT_DM_RV_IDX') FROM DUAL;

И если вы забыли, какие параметры вы выбрали во время индексирования:

SELECT * FROM CTXSYS.CTX_PARAMETERS;

Удачного индексирования!

10
ответ дан 2 December 2019 в 22:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: