如何使用USE
來源:互聯網
上載者:User
使用USE_CONCAT提示
--Use USE_CONCAT hints in Oracle
Last Updated: Thursday, 2004-11-18 21:48 Eygle
USE_CONCAT提示強迫最佳化器擴充查詢中的每一個OR謂詞為獨立的查詢塊.
最後合并所有查詢塊的結果,返回結果集給使用者。
當使用多個in-lists查詢時,Oracle可能選擇把單個查詢擴充為多個查詢塊。
使用USE_CONCAT提示樣本:
1.使用scott使用者及標準表進行測試
$ sqlplus scott/tigerSQL*Plus: Release 9.2.0.4.0 - Production on Wed Nov 17 15:17:51 2004Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.Connected to:Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit ProductionWith the Partitioning, OLAP and Oracle Data Mining optionsJServer Release 9.2.0.4.0 - ProductionSQL> set autotrace onSQL> select * from emp where empno in (7788,7900); EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7788 SCOTT ANALYST 7566 19-APR-87 3000 20 7900 JAMES CLERK 7698 03-DEC-81 950 30Execution Plan---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=2 Bytes=74) 1 0 TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=2 Bytes=74)--注意,此處Oracle選擇了全表掃描,因為成本較低。Statistics---------------------------------------------------------- 0 recursive calls 0 db block gets 4 consistent gets 0 physical reads 0 redo size 1032 bytes sent via SQL*Net to client 655 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 2 rows processed
2.添加提示
SQL> select /*+ use_concat */ * from emp where empno in (7788,7900); EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO---------- ---------- --------- ---------- --------- ---------- ---------- ---------- 7900 JAMES CLERK 7698 03-DEC-81 950 30 7788 SCOTT ANALYST 7566 19-APR-87 3000 20Execution Plan---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=2 Bytes=74) 1 0 CONCATENATION 2 1 TABLE ACCESS (BY INDEX ROWID) OF 'EMP' (Cost=2 Card=1 Bytes=37) 3 2 INDEX (UNIQUE SCAN) OF 'PK_EMP' (UNIQUE) (Cost=1 Card=14) 4 1 TABLE ACCESS (BY INDEX ROWID) OF 'EMP' (Cost=2 Card=1 Bytes=37) 5 4 INDEX (UNIQUE SCAN) OF 'PK_EMP' (UNIQUE) (Cost=1 Card=14)--使用use_concat提示以後,Oracle將in-lists條件展開為兩個查詢塊,分別使用索引,最後CONCATENATION得到最後輸出。--注意,這裡強制使用索引導致成本上升為4。Statistics---------------------------------------------------------- 0 recursive calls 0 db block gets 4 consistent gets 0 physical reads 0 redo size 1032 bytes sent via SQL*Net to client 655 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 2 rows processedSQL>
3.Oracle對於執行計畫的改寫
對於inlist查詢,Oracle通常會進行改寫,將形如
select ..... from ....... where ....in (..........)
的sql語句,改寫為union all的形式來執行,這個改寫通常是潛在的。
然而這一改寫可能存在問題,如果inlist中的值比較多的話,CBO花在分析執行路徑上的時間和成本都會相當大,此時我們通常需要阻止Oracle的這一展開操作.
我們可以通過NO_EXPAND提示來阻止Oracle進行這樣的改寫。
那麼實際上,在這裡,USE_CONCAT和NO_EXPAND成了互為"反函數"。在使用了NO_EXPAND提示後,從Oracle8之後,Oracle會使用"inlist iterator"
方式來執行SQL,這樣可以用到index。
本文作者:
eygle,Oracle技術粉絲,來自中國最大的Oracle技術論壇itpub.
www.eygle.com是作者的個人網站.你可通過Guoqiang.Gai@gmail.com來聯絡作者.歡迎技術探討交流以及連結交換.
原文出處:
http://www.eygle.com/sql/How.to.Use.USE_CONCAT.hints.in.Oracle.htm