FIRST_ROWS和FIRST_ROWS(N)的區別 (zt)
http://yangtingkun.itpub.net/post/468/228323
早就聽說FIRST_ROWS和FIRST_ROWS(N)有區別,一直也沒有測試出來到底差異在哪裡,沒想到測試全文索引的時候,發現了二者的差異。
按照Oracle文件的說法,FIRST_ROWS並不完全是CBO模式,還包含了大量的基於規則的最佳化方式。而9i新增的FIRST_ROWS(N)則完全基於代價的方式。
[@more@]SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30), DOCS VARCHAR2(4000));
表已建立。
SQL> INSERT INTO T
2 SELECT ROWNUM, OBJECT_NAME,
3 OWNER || ' ' || OBJECT_TYPE || ' ' || OBJECT_NAME
4 FROM DBA_OBJECTS;
已建立31313行。
SQL> CREATE INDEX IND_T_NAME ON T (NAME);
索引已建立。
SQL> CREATE INDEX IND_T_DOCS ON T (DOCS) INDEXTYPE IS CTXSYS.CONTEXT;
索引已建立。
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(USER, 'T', METHOD_OPT => 'FOR ALL INDEXED COLUMNS SIZE 100')
PL/SQL 過程已成功完成。
SQL> EXEC DBMS_STATS.GATHER_INDEX_STATS(USER, 'IND_T_DOCS')
PL/SQL 過程已成功完成。
SQL> SET AUTOT ON EXP
SQL> COL DOCS FORMAT A50
SQL> SELECT * FROM T
2 WHERE CONTAINS(DOCS, 'SYS', 1) > 0
3 AND NAME = 'DUAL'
4 ORDER BY SCORE(1);
ID NAME DOCS
---------- ------------------------------ ---------------------------------
7112 DUAL SYS TABLE DUAL
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=1 Bytes=74)
1 0 SORT (ORDER BY) (Cost=5 Card=1 Bytes=74)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=2 Card=1 Bytes=74)
3 2 INDEX (RANGE SCAN) OF 'IND_T_NAME' (NON-UNIQUE) (Cost=1 Card=2)
根據列的資料的分佈以及索引的統計資訊,Oracle在這裡選擇了普通索引,而沒有選擇全文索引。
下面就可以看到兩個提示FIRST_ROWS和FIRST_ROWS(N)的區別了:
SQL> SELECT /*+ FIRST_ROWS */ * FROM T
2 WHERE CONTAINS(DOCS, 'SYS', 1) > 0
3 AND NAME = 'DUAL'
4 ORDER BY SCORE(1);
ID NAME DOCS
---------- ------------------------------ ----------------------------------
7112 DUAL SYS TABLE DUAL
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=2643 Card=1 Bytes=74)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=2640 Card=1 Bytes=74)
2 1 DOMAIN INDEX OF 'IND_T_DOCS' (Cost=2369 Card=2)
SQL> SELECT /*+ FIRST_ROWS(1) */ * FROM T
2 WHERE CONTAINS(DOCS, 'SYS', 1) > 0
3 AND NAME = 'DUAL'
4 ORDER BY SCORE(1);
ID NAME DOCS
---------- ------------------------------ ----------------------------------
7112 DUAL SYS TABLE DUAL
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: FIRST_ROWS (Cost=5 Card=1 Bytes=74)
1 0 SORT (ORDER BY) (Cost=5 Card=1 Bytes=74)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'T' (Cost=2 Card=1 Bytes=74)
3 2 INDEX (RANGE SCAN) OF 'IND_T_NAME' (NON-UNIQUE) (Cost=1 Card=2)
FIRST_ROWS(N)完全根據統計資訊來進行判斷,而FIRST_ROWS包含了一些預設的規則在其中,因此,FIRST_ROWS選擇了域索引,而沒有選擇代價更小的普通索引。
可能也是出於上述的考慮,Oracle選擇預設的CBO模式時,選擇了ALL_ROWS而不是FIRST_ROWS。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/35489/viewspace-997007/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- FIRST_ROWS和FIRST_ROWS_n的區別
- first_rows更傾向使用nested loop操作。OOP
- 【優化】ALL_ROWS模式和FIRST_ROWS模式的適用場景優化模式
- 【最佳化】ALL_ROWS模式和FIRST_ROWS模式的適用場景模式
- char(n)和varchar2(n)區別
- MySQL中資料型別(char(n)、varchar(n)、nchar(n)、nvarchar(n)的區別)MySql資料型別
- mysql的varchar(N)和int(N)的含義及其與char區別MySql
- Oracle的優化器:RBO/CBO,RULE/CHOOSE/FIRST_ROWS/ALL_ROWS 名詞解釋Oracle優化
- EXISTS、IN、NOT EXISTS、NOT IN的區別(ZT)
- 當Oracle9i的OPTIMIZER_MODE = FIRST_ROWS時EXP過慢的解決方法Oracle
- FIRST_ROWS優化模式訪問遠端表可能導致錯誤結果(二)優化模式
- FIRST_ROWS優化模式訪問遠端表可能導致錯誤結果(一)優化模式
- eventlet 的 spawn_n 和 spawn 有什麼區別?
- v$sqlarea,v$sql,v$sqltext的區別和聯絡(zt)SQL
- Oracle各版本區別(zt)Oracle
- zt_orafaq_delete與truncate的區別delete
- standby_archive_dest和log_archive_dest_n區別Hive
- 360N7對比N6 Pro的區別對比 60N7和360N6 Pro哪個好?
- ../和./和/的區別
- VARCHAR2(N CHAR)與VARCHAR2(N)的區別[Oracle基礎]Oracle
- 360n4s和紅米4區別對比評測
- se16與se16n的區別
- 360手機N4S和360手機N4區別對比評測
- 和 的區別
- as 和 with的區別
- ||和??的區別
- /*和/**的區別
- LinkedList和ArrayList的區別、Vector和ArrayList的區別
- http和https的區別/get和post的區別HTTP
- Oracle FailSafe與rac的聯絡與區別(zt)OracleAI
- EXP匯出引數compress=y(n)的區別
- ./ 和sh 的區別
- JQuery this和$(this)的區別jQuery
- jquery $(this) 和this的區別jQuery
- T和?的區別
- ++a和a++的區別
- makefile =和:=的區別
- 紅米Pro和360手機N4S區別對比評測