Ste*_*fan 12 oracle full-text-indexing database-tuning
我们使用Oracle Text CTXSYS.CONTEXT索引来索引包含元信息的大约50万行.信息分布在两个表中,这两个表由索引器在运行时调用的过程(功能索引)组合在一起.
当我在本地机器(简单的双核笔记本)上运行CREATE INDEX时,索引在大约3分钟内构建.在我们的数据库服务器上运行在具有8个内核和16G内存的Solaris上,需要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
Run Code Online (Sandbox Code Playgroud)
这些是偏好
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;
Run Code Online (Sandbox Code Playgroud)
现在我们创建索引
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;
Run Code Online (Sandbox Code Playgroud)
数据主要包括一个简单的标题或作者姓名+一个<1k文本的简短描述.
我尝试使用所涉及的内存设置和PARALLEL参数稍微玩一下,但没有任何成功.所以这里有我的问题:
Ste*_*fan 10
我们终于想出了如何对索引进行拆分同步.以下是一些显示我们所做工作的基本步骤:
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
');
Run Code Online (Sandbox Code Playgroud)
看到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(是的,你可能会打电话给你对于管理员).通过查询索引元表找出新创建的索引所具有的ID:
SELECT IDX_ID FROM CTXSYS.CTX_INDEXES WHERE IDX_NAME ='concat_DM_RV_idx';
Run Code Online (Sandbox Code Playgroud)
3)注意这是在一张黄色片段产生索引ID并执行此插入语句作为CTXSYS作用,并用食指ID和<>与该指数是建立在表的名称替换<>.唯一行标识符可以是某种文档ID或任何类型的可计数语句,用于创建表的唯一数据块:
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!
Run Code Online (Sandbox Code Playgroud)
该"50.000",标志着这取决于你basetabel的珍异那将在未决行表中插入有效载荷为索引的行数.根据自己的需要调整它.
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
);
Run Code Online (Sandbox Code Playgroud)
即将于任何的行数,您已插入在步骤3索引过程)要运行一个块重复步骤3)与下一50.000左右行("里50.000和100.000之间的ID")
如果您不小心在同一组行上运行索引器,索引将强烈碎片化.清理它的唯一方法是使用REBUILD参数优化索引.在我们的本地机器上,由于索引器不必运行但只重新排列索引表的内容,因此速度非常快:
CALL CTX_DDL.OPTIMIZE_INDEX('CONCAT_DM_RV_IDX', 'REBUILD');
Run Code Online (Sandbox Code Playgroud)
如果您需要有关索引状态和大小的元信息,可以询问CTX_REPORT包:
SELECT CTX_REPORT.INDEX_SIZE('CONCAT_DM_RV_IDX') FROM DUAL;
Run Code Online (Sandbox Code Playgroud)
如果您忘记了在索引时选择了哪些参数:
SELECT * FROM CTXSYS.CTX_PARAMETERS;
Run Code Online (Sandbox Code Playgroud)
快乐索引!
| 归档时间: |
|
| 查看次数: |
16479 次 |
| 最近记录: |