首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle資料庫中文全文索引完整指南:架構、配置與效能實測

     編輯:Oracle 資料庫基礎

一、發展脈絡

Oracle全文檢索技術經歷演進:Oracle 8i之前稱Oracle ConText Cartridge,8/8i時期為Oracle interMedia Text,9i起更名為Oracle Text,賦予資料庫強大的文本檢索與智慧管理能力。

二、索引建立核心邏輯流程

  1. 資料儲存:掃描表所有列,讀取欄位資料(或作為文件指標)
  2. 過濾器:提取二進位文件(Word/PDF)轉為文字表現(XML/HTML等)
  3. 分段器:將不同格式轉為純文字,處理標記、移除不可見資訊、重新格式化
  4. 詞法分析器:將純文字拆解為離散Token(支援空白分隔語言與亞洲語言專用分析器)
  5. 索引引擎:建立反向索引,儲存Token、文件段偏移量、非索引字列表

三、權限需求

使用Oracle Text需具備CTXAPP角色或為CTXSYS使用者。CTXAPP可執行:建立索引、管理Text資料字典、查詢、使用PL/SQL套件。

四、索引配置八大類別與物件

每個索引包含多個類別,每類別含預定義物件,物件再透過屬性客製化:

  • 儲存類:BASIC_STORAGE(索引表空間參數)
  • 資料儲存類:DIRECT_DATASTORE、FILE_DATASTORE、URL_DATASTORE等7種
  • 文件段組類:AUTO_SECTION_GROUP、HTML_SECTION_GROUP、XML_SECTION_GROUP等
  • 相關詞表類:BASIC_WORDLIST(詞幹/模糊查詢選項)
  • 索引集類:BASIC_INDEX_SET(用於CTXCAT索引)
  • 詞法分析器類:BASIC_LEXER、CHINESE_LEXER、CHINESE_VGRAM_LEXER等8種
  • 過濾器類:NULL_FILTER、INSO_FILTER、CHARSET_FILTER等
  • 非索引字表類:BASIC_STOPLIST、MULTI_STOPLIST

五、中文全文索引實作步驟

1. 建立偏好設定

BEGIN
  -- 中文詞法分析器
  CTX_DDL.DROP_PREFERENCE('cnlex');
  CTX_DDL.CREATE_PREFERENCE('cnlex', 'CHINESE_LEXER');
  
  -- 相關詞表:啟用前綴/子字串索引
  CTX_DDL.CREATE_PREFERENCE('mywordlist', 'BASIC_WORDLIST');
  CTX_DDL.SET_ATTRIBUTE('mywordlist', 'PREFIX_INDEX', 'TRUE');
  CTX_DDL.SET_ATTRIBUTE('mywordlist', 'PREFIX_MIN_LENGTH', '1');
  CTX_DDL.SET_ATTRIBUTE('mywordlist', 'PREFIX_MAX_LENGTH', '5');
  CTX_DDL.SET_ATTRIBUTE('mywordlist', 'SUBSTRING_INDEX', 'YES');
END;

2. 建立Context索引

CREATE INDEX idx_person_desc ON personinfo(persondesc)
INDEXTYPE IS CTXSYS.CONTEXT
PARAMETERS (
  'DATASTORE CTXSYS.DIRECT_DATASTORE
   FILTER CTXSYS.NULL_FILTER
   LEXER cnlex
   WORDLIST mywordlist'
);
-- 關鍵:必須使用NULL_FILTER,INSO_FILTER無法支援中文全文索引

3. 索引同步與優化

-- 同步:將新Token寫入$I表
EXEC CTX_DDL.SYNC_INDEX('idx_user_info', '20M');

-- 優化:清除已刪除Token
EXEC CTX_DDL.OPTIMIZE_INDEX('idx_user_info', 'FULL');

六、三大中文詞法分析器深度解析

分析器適用語言分詞邏輯優缺點
BASIC_LEXER英文/西歐語空白+標點分隔效率高,但中文會將整句視為單一Token,失去檢索能力
CHINESE_VGRAM_LEXER中文(所有字符集)雙字元重疊(N-gram)「一網打盡」但產生大量無意義Token(如「民站」),效率差
CHINESE_LEXER中文(僅UTF8)詞彙辨識+智慧分詞識別常用詞彙,移除無意義Token,效率大幅提升,推薦

注意:Oracle 9.2+已改善CHINESE_LEXER的字符集限制,實測可在非UTF8環境運作。

七、索引維護:同步與優化機制

建立索引後,Oracle自動產生DR$indexname$I/K/R/N四張表,其中$I表最關鍵,儲存Token、出現位置、次數、Hash值。

  • SYNC:增量更新,將新Token寫入$I表
  • OPTIMIZE:清除垃圾,移除已刪除文件的Token

建立DBMS_JOB或DBMS_SCHEDULER定期執行同步/優化,確保檢索結果即時性。

八、驗證索引建立成功

  1. 檢查DR$indexname$I表是否存在
  2. 使用CONTAINS查詢:SELECT * FROM personinfo WHERE CONTAINS(persondesc, '關鍵字', 1) > 0
  3. 若報錯ORA-20000: DRG-10599: 列沒有編制索引則建立失敗

九、實測效能數據 (18萬筆測試資料)

測試案例查詢方式耗時備註
測試一LIKE '%大學%'40.688秒全表掃描
測試二LIKE '%1999%'47.218秒全表掃描
測試七CONTAINS '1999' (CHINESE_LEXER)首次469ms,後續~210ms英文查詢極快
測試八CONTAINS '大學' (CHINESE_LEXER)首次9.359秒,後續~210ms中文首次較慢,但後續極快
測試九DBMS_LOB.INSTR '大學' (有索引)54.953秒未使用索引,仍全表掃描

結論:CHINESE_LEXER配合CONTAINS查詢,中文檢索效能較LIKE提升40-200倍。但實測發現CONTAINS回傳筆數略少於LIKE,需評估業務容忍度。整體來說,Oracle中文全文索引在9i後已具備實用價值,建議生產環境採用CHINESE_LEXER+NULL_FILTER組合。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved