Oracle在執行一個SQL之前首先要分析一下語句的執行計劃然後再按執行計劃去執行分析語句的執行計劃的工作是由優化器(Optimizer)來完成的不同的情況一條SQL可能有多種執行計劃但在某一時點一定只有一種執行計劃是最優的花費時間是最少的相信你一定會用Pl/sql DeveloperToad等工具去看一個語句的執行計劃不過你可能對RuleChooseFirst rowsAll rows這幾項有疑問因為我當初也是這樣的那時我也疑惑為什麼選了以上的不同的項執行計劃就變了?
優化器的優化方式
Oracle的優化器共有兩種的優化方式即基於規則的優化方式(RuleBased Optimization簡稱為RBO)和基於代價的優化方式(CostBased Optimization簡稱為CBO)
ARBO方式優化器在分析SQL語句時所遵循的是Oracle內部預定的一些規則比如我們常見的當一個where子句中的一列有索引時去走索引
BCBO方式依詞義可知它是看語句的代價(Cost)了這裡的代價主要指Cpu和內存優化器在判斷是否用這種方式時主要參照的是表及索引的統計信息統計信息給出表的大小 有少行每行的長度等信息這些統計信息起初在庫內是沒有的是你在做analyze後才出現的很多的時侯過期統計信息會令優化器做出一個錯誤的執行計劃因些我們應及時更新這些信息在Oracle及以後的版本Oracle列推薦用CBO的方式
我們要明了不一定走索引就是優的 比如一個表只有兩行數據一次IO就可以完成全表的檢索而此時走索引時則需要兩次IO這時對這個表做全表掃描(full table scan)是最好的
優化器的優化模式(Optermizer Mode)
優化模式包括RuleChooseFirst rowsAll rows這四種方式也就是我們以上所提及的如下我解釋一下
Rule:不用多說即走基於規則的方式
Choolse:這是我們應觀注的默認的情況下Oracle用的便是這種方式指的是當一個表或或索引有統計信息則走CBO的方式如果表或索引沒統計信息表又不是特別的小而且相應的列有索引時那麼就走索引走RBO的方式
First Rows:它與Choose方式是類似的所不同的是當一個表有統計信息時它將是以最快的方式返回查詢的最先的幾行從總體上減少了響應時間
All Rows:也就是我們所說的Cost的方式當一個表有統計信息時它將以最快的方式返回表的所有的行從總體上提高查詢的吞吐量沒有統計信息則走基於規則的方式
如何設定選用哪種優化模式
◆AInstance級別
我們可以通過在initora文件中設定OPTIMIZER_MODE=RULEOPTIMIZER_MODE=CHOOSEOPTIMIZER_MODE=FIRST_ROWSOPTIMIZER_MODE=ALL_ROWS去選用所提的四種方式如果你沒設定OPTIMIZER_MODE參數則默認用的是Choose這種方式
◆BSessions級別
通過SQL> ALTER SESSION SET OPTIMIZER_MODE=;來設定
◆C語句級別
這些需要用到Hint比如:
SQL> SELECT /*+ RULE */ auserid
bname
bdepart_name
FROM tf_f_yhda a
tf_f_depart b
WHERE auserid=buserid;
這個listener還沒有配置extproc 因此需要為它增加對extproc的監聽辦法就是分別增加description 和 sid_desc 修改後的listnerora 如下
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = MYDATABASE)(PORT = ))
)
(DESCRIPTION =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
)
)
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = mydatabaseworld)
(ORACLE_HOME = /u/app/oracle/product/)
(SID_NAME = mydatabase)
)
(SID_DESC =
(PROGRAM = extproc)
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u/app/oracle/product/)
)
)
注意上面的host global_dbnamesid_nameoracle_home應填寫你的數據庫的實際值但program一項必須填寫extproc
設置tnsnamesora
其次要配置服務器端的tnsnamesora文件該文件的位置在$ORACLE_HOME/network/admin下面同樣可以通過運行netasst來進行配置
在tnsnamesora文件中需要增加如下一項
EXTPROC_CONNECTION_DATAEXTPROC_CONNECTION_DATAWORLD =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC))
)
(CONNECT_DATA =
(SID = PLSExtProc)
)
)
注意其中KEY 和SID必須與listenerora中的key 和sid_name對應相同
三.設置詞法分析器(lexer)
Oracle 缺省使用basic_lexer這個分析器basic_lexer針對英語要指定使用中文分析器 操作步驟
. 用ctxsys用戶登陸intermedia text manager口令ctxsys:
.選擇首選項——〉語言指示器——〉創建輸入指示器的名字如chinese_lexer選擇lexer下的chinese_vgrnm_lexer
.建立intermedia索引指定索引名選擇方案和表下的字段例如system方案下的DOM__DOCLIB中的CURRENTTEXT字段首選項中選擇chinese_lexer
這樣建立的全文檢索索引就會使用chinese_vgram_lexer作為分析器
.在索引建好後在該用戶下查到Oracle自動產生了以下幾個表可以使用dba studio查看(假設索引名為myindex)
DR$myindex$IDR$myindex$KDR$myindex$RDR$myindex$N
其中以I表最重要查詢該表
select token_text token_count from DR$I_RSK$I where rownum<=;
可以看到該表中保存的是Oracle分析你的文檔後生成的term記錄包括term出現的位置次數hash值等
四.使用job定時同步和優化
在intermedia索引建好後如果表中的數據發生變化增加或修改了記錄由於對表所發生的任何dml語句都不會自動修改索引因此必須定時同步(sync)和優化(optimize)索引以正確反映數據的變化
同步(sync):將新的term 保存到I表
優化(optimize):清除I表的垃圾主要是將已經被刪除的term從I表刪除
Oracle提供了一個ctx server來做這個同步和優化的工作只需要在後台運行這個進程它會監視數據的變化及時進行同步但存在許多問題可以用下的兩個job來完成(該job要建在和表同一個用戶下)
sync:
VARIABLE jobno number;
BEGIN
DBMS_JOBSUBMIT(:jobnoctx_ddlsync_index(myindex);
SYSDATE SYSDATE + (//));
commit;
END;
optimizer
VARIABLE jobno number;
BEGIN
DBMS_JOBSUBMIT(:jobnoctx_ddloptimize_index(myindexFULL);
SYSDATE SYSDATE + );
commit;
END;
注釋第一個job的SYSDATE + (//)是指每隔分鐘同步一次第二個job的SYSDATE + 是每隔天做一次全優化至於具體的時間間隔大家可以根據各自的應用需要來靈活應用
From:http://tw.wingwit.com/Article/program/Oracle/201311/18793.html