Oracle 8.1.6/8.1.7 的 Intermedia Text 建立索引極快(65 萬筆約 20 分鐘,同步 1 分鐘),但設定複雜度遠高於 SQL Server 2000。本文記錄 HP-UX / Solaris 實戰部署經驗與錯誤排查。
ctxsys 使用者與 ctxapp 角色是否存在。$ORACLE_HOME/bin/dbassist → Modify Database → 勾選 JServer 與 Intermedia(Intermedia 依賴 JServer)。操作前務必完整備份資料庫。Intermedia 透過 extproc 呼叫外部斷詞庫,Listener 必須監聽 IPC 協定。
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = MYDB)(PORT = 1521)))
(DESCRIPTION = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC)))
)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC = (GLOBAL_DBNAME = mydb.world)(ORACLE_HOME = /u01/app/oracle/product/8.1.6)(SID_NAME = mydb))
(SID_DESC = (PROGRAM = extproc)(SID_NAME = PLSExtProc)(ORACLE_HOME = /u01/app/oracle/product/8.1.6))
)
PROGRAM = extproc 固定寫法,KEY = EXTPROC 需與 tnsnames.ora 一致。
EXTPROC_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST = (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC)))
(CONNECT_DATA = (SID = PLSExtProc))
)
lsnrctl stop; lsnrctl start
tnsping extproc_connection_data
# 成功顯示: OK (140 msec)
| Lexer | 適用語言 | 字符集支援 | 機制 | 優缺點 |
|---|---|---|---|---|
| BASIC_LEXER | 英文 | 所有 | 空格/標點切分,停用詞過濾 | 中文會將整句當一個 Token,失效 |
| CHINESE_VGRAM_LEXER | 中文 | 所有中文字符集 | 雙字元滑動窗口 (N-gram) | 機械切分產生無意義 Token (如「民站」),索引大、效率低 |
| CHINESE_LEXER | 中文 | 僅 UTF8 | 詞典式切分,識別常用詞彙 | 效率高、索引小,但需 UTF8 資料庫 |
-- 1. 建立 Preference
BEGIN CTX_DDL.CREATE_PREFERENCE('my_lexer','CHINESE_VGRAM_LEXER'); END;
/
-- 2. 建立索引時指定
CREATE INDEX myidx ON mytable(content) INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS('LEXER my_lexer');
DML 不會自動更新索引,需排程同步:
-- 同步:每 15 分鐘
VARIABLE jobno NUMBER;
BEGIN
DBMS_JOB.SUBMIT(:jobno, 'CTX_DDL.SYNC_INDEX(''myidx'');', SYSDATE, 'SYSDATE + 1/24/4');
COMMIT;
END;
/
-- 優化:每天一次 FULL 優化 (清除已刪 Token)
BEGIN
DBMS_JOB.SUBMIT(:jobno, 'CTX_DDL.OPTIMIZE_INDEX(''myidx'',''FULL'');', SYSDATE, 'SYSDATE + 1');
COMMIT;
END;
/
官方 ctxsrv 進程穩定性較差,Oracle 支援建議改用 Job 方式。
| 錯誤代碼 | 原因 | 解決 |
|---|---|---|
| DRG-10595 / ORA-01480 | 8i NLS Bug | 同步前執行 ALTER SESSION SET NLS_LANGUAGE=AMERICAN; |
| ORA-29855 / DRG-50704 / ORA-28575 | extproc 配置錯誤 | 檢查 listener.ora/tnsnames.ora IPC 設定,重啟 Listener |
| ORA-29861: domain index marked loading/failed/unusable | 索引狀態異常 | ALTER INDEX myidx REBUILD ONLINE PARAMETERS('SYNC'); 或 DROP INDEX myidx FORCE; |
| DRG-11102: lexer can't analyze ZHS16GBK | CHINESE_LEXER 僅支援 UTF8 | 改用 VGRAM 或將資料庫遷移至 UTF8 (需評估應用相容性) |
| ORA-04030: process memory exceeded (cursor work heap) | 單列超過 2000 字元觸發 8.1.7 Bug 1391737 | 降低 SORT_AREA_SIZE 或打 8.1.7.1B Patch |
| 升級後 ORA-06508: PL/SQL: cannot find program unit | Intermedia 套件失效 | 以 ctxsys 執行 $ORACLE_HOME/ctx/admin/dr0pkh.sql 及 dr0plb.sql 重編譯 |
SELECT idx_name, idx_status FROM ctxsys.ctx_indexes;
SELECT token_text, token_count FROM dr$myidx$i WHERE rownum <= 20;
Intermedia 功能強大(24 種運算子、字典、主題搜尋),掌握上述部署細節即能穩定上線。