Ответ 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;
Счастливое индексирование!