oracle資料庫驅動表
出處:http://blog.itpub.net/71225/viewspace-828310/http://www.itpub.net/showthread.php?s=&threadid=144375&perpage=10&pagenumber=2
rule 下所謂驅動表還有 nested loops and hash join 之份我們以 nested loop 為例:
如果兩個表連線欄位都沒有索引(通常這個時候是 sort merge / hash join),則驅動表會選擇後者
若兩個表其中有一個有索引而另外一個沒有索引,則驅動表是沒有索引那一個,跟順序無關
若兩個表都有索引,則驅動表為 後面 那一個表
所以事實上,RULE下,只有在兩個表都存在連線欄位的索引的情況下才需要考慮順序問題
也就是小表放在後面大表放在前面(當然到底哪個好這實際上還跟 符合條件的記錄數、資料分佈等因素相關!!!,所以應該以實際測試為準)
關鍵的是明白執行計劃而不在於記什麼規則
舉例,表連線返回一條記錄存在兩個表,一個 10條記錄 ,一個1000萬條記錄若2表都存在連線欄位索引,
若以小表為驅動表,則代價: 10* (通過索引在大表查詢一條記錄的代價)
若以大表為驅動表:1000萬 * (通過索引在小表中查詢一條記錄的代價)
通過索引獲取一條記錄,10rows的表,代價通常在 3 blocks 索引2塊,表一塊
而如果是1000萬的表,索引可能達到4塊表一塊
這樣一來參考上面的計算,你說哪個更好?很顯然!
小表查詢參考SQL> create table test as select * from all_objects where rownum < 11;Table created.SQL> create index test_index on test(object_id);Index created.SQL> select object_id from test;OBJECT_ID----------1815977814841198912254917099177124287101071913510 rows selected.Execution Plan----------------------------------------------------------0 SELECT STATEMENT Optimizer=CHOOSE1 0 TABLE ACCESS (FULL) OF 'TEST'Statistics----------------------------------------------------------0 recursive calls12 db block gets6 consistent gets0 physical reads0 redo size736 bytes sent via SQL*Net to client425 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)10 rows processedSQL> select * from test where object_id = 4287;OWNER OBJECT_NAME------------------------------ ------------------------------SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE------------------------------ ---------- -------------- ------------------CREATED LAST_DDL_ TIMESTAMP STATUS T G S--------- --------- ------------------- ------- - - -SYS /1033c8a_SqlTypeWithMethods4287 JAVA CLASS14-NOV-00 03-JUL-03 2003-07-03:11:18:19 INVALID N N NExecution Plan----------------------------------------------------------0 SELECT STATEMENT Optimizer=CHOOSE1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST'2 1 INDEX (RANGE SCAN) OF 'TEST_INDEX' (NON-UNIQUE)Statistics----------------------------------------------------------0 recursive calls0 db block gets3 consistent gets0 physical reads0 redo size1157 bytes sent via SQL*Net to client425 bytes received via SQL*Net from client2 SQL*Net roundtrips to/from client0 sorts (memory)0 sorts (disk)1 rows processedSQL>如果是 CBO 下則跟順序無關