1. 程式人生 > >oracle驅動表以及如何確定驅動表

oracle驅動表以及如何確定驅動表

驅動表普遍認為是由SQL語句的寫法決定的,簡單的說,就是FROM語句後面的表列表中的最後一個。由於SQL語句是從後向前進行分析,Oracle會根據FROM語句從後到前將各個表依次連線起來。

SQL> CREATE TABLE T1 AS SELECT * FROM USER_TABLES;

表已建立。

SQL> CREATE TABLE T2 AS SELECT * FROM USER_INDEXES;

表已建立。

SQL> SET AUTOT ON EXP
SQL> SELECT COUNT(*) FROM T1, T2
2 WHERE T1.TABLE_NAME = T2.TABLE_NAME;

COUNT(*)
----------
37

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 MERGE JOIN
3 2 SORT (JOIN)
4 3 TABLE ACCESS (FULL) OF 'T2'
5 2 SORT (JOIN)
6 5 TABLE ACCESS (FULL) OF 'T1'

SQL> SELECT COUNT(*) FROM T2, T1
2 WHERE T1.TABLE_NAME = T2.TABLE_NAME;

COUNT(*)
----------
37

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 MERGE JOIN
3 2 SORT (JOIN)
4 3 TABLE ACCESS (FULL) OF 'T1'
5 2 SORT (JOIN)
6 5 TABLE ACCESS (FULL) OF 'T2'

根據這個例子,可以看出,SQL語句的寫法對於驅動表的影響。

然而,實際上驅動表和連線順序的選擇要比上面的觀點複雜的多,下面對稍微調整一下這個例子。

SQL> ALTER TABLE T1 ADD CONSTRAINT PK_T1 PRIMARY KEY (TABLE_NAME);

表已更改。

SQL> SELECT COUNT(*) FROM T1, T2
2 WHERE T1.TABLE_NAME = T2.TABLE_NAME;

COUNT(*)
----------
37

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 NESTED LOOPS
3 2 TABLE ACCESS (FULL) OF 'T2'
4 2 INDEX (UNIQUE SCAN) OF 'PK_T1' (UNIQUE)

SQL> SELECT COUNT(*) FROM T2, T1
2 WHERE T1.TABLE_NAME = T2.TABLE_NAME;

COUNT(*)
----------
37

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 NESTED LOOPS
3 2 TABLE ACCESS (FULL) OF 'T2'
4 2 INDEX (UNIQUE SCAN) OF 'PK_T1' (UNIQUE)

僅僅是給T1增加了一個主鍵,就發現不管SQL語句怎麼寫驅動表都是T2。

即使是RBO,確定表連線順序的規則也是比較複雜的:

1.優化器產生一系列連線順序,每次均把不同的表作為驅動表。而且,優化器根據下面的演算法產生每個連線順序。

為了確定連線順序中各個表的位置,優化器根據RBO執行計劃的排名,在剩餘的表中找到表訪問路徑排名最高的表,然後不斷的重複這個過程,依次確定連線順序中每個表的前後順序。

對於連線順序中的每張表,優化器根據執行計劃的排名選擇一種連線方式將當前表和前面的表或資料來源連線在一起。

2.優化器在執行計劃的結果集中進行選擇。優化器的目標是最大程度的選擇內部表採用索引掃描方式的NESTED LOOPS連線操作。

通常情況下,優化器在選擇執行計劃時,不會考慮表在FROM語句中出現的順序。優化器依次根據下面的規則來作出選擇

優化器選擇執行計劃使得內部表為全表掃描的NESTED LOOPS連線儘可能的少;

如果採用上面的條件出現了平局的情況,則優化器選擇儘可能少出現SORT MERGE操作的執行計劃;

如果仍然出現平局的情況,則優化器將選擇表訪問路徑中排名最高的表作為驅動表;

如果這時仍然是平局,則優化器會把FROM語句中最後出現的表最為驅動表。