Re: [SQL ] 最近遇到的一個問題,請求解答
※ 引述《qrtt1 (愚人)》之銘言:
: 如果你只用到 B.xxx
: 就沒有必要把 A, B 都拿來做卡氏積
: select A.*, B_partial.xxx
: from A, (select B.xxx, B.id from B) B_partial
: WHERE B_partial.id = A.id;
: 單純取用 B.xxx 與 B.id 就可以了
這是比較屬於學術上的說法, 在實作上, 絕大部份的情況, 這兩種
寫法對 database 來說是一樣的. 以 Oracle 為例:
SQL> explain plan for select a.*, b.id2
from test a, test2 b
where a.id1=b.id1;
SQL> explain plan for select a.*, b_partial.id2
from test a, (select id1, id2 from test2) b_partial
where a.id1=b_partial.id1;
這兩種寫法的 execution plan 是完全相同, 如下:
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10M| 661M| 932 (19)| 00:00:12 |
|* 1 | HASH JOIN | | 10M| 661M| 932 (19)| 00:00:12 |
| 2 | TABLE ACCESS FULL| TEST | 12010 | 457K| 9 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| TEST2 | 1067K| 26M| 777 (4)| 00:00:10 |
---------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("A"."ID1"="B"."ID1")
簡單地說, 第二個寫法雖然用了 b_partial, 但最後產生的 plan 還是在處理A和B,
和第一個寫法相同, 並非照著字面上的文句來處理. 這就像是 view 一樣, 對
database 來說是透明的. 在這個例子, 如果先把 b_partial 定義成一個 view,
產生出來的 plan 仍是不變.
會照成這個情形的原因很簡單, 那就是 database 實際上並不會真的產生卡氏積
或是類似卡氏積的東西, 反而只是以類似 pointer 的形式, 記錄 A 的第m個row
及 B 的第n個row 符合 where 的條件, 再把結果存到 cursor 中. 換句話說,
最後 select 的 column 如何組合並不會影響 execution plan, 而是在 where
中用到的 column 會影響到.
在少數的情況下, 這兩種寫法的執行速度會有差別, 但差別的地方不在 plan, 也和
卡氏積無關. 會有差別的主要原因嚴格上要算是個 bug 或是 future enhancement,
算是特例的情況.
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 64.9.239.175
※ 編輯: noguest 來自: 64.9.239.175 (03/28 13:12)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 9 之 9 篇):
Database 近期熱門文章
PTT數位生活區 即時熱門文章