解決方案的一個參考表2比較兩種查詢:
select t1.stuff
, max(case when t1.sender_id = t2.id then t2.name end) as sender_name
, max(case when t1.recipient_id = t2.id then t2.name end) as recipint_name
from t1
join t2
on t2.id in (t1.sender_id, t1.recipient_id)
group by t1.stuff;
這是一個有點亂,但也有它就會得心應手情況。
我創建的表和與萬行,每行(DB2 Express-C中,10.5修訂包1)釀它們:
db2 "create table t1 (stuff int not null primary key, sender_id int not null, recipient_id int not null)"
db2 "create table t2 (id int not null primary key, name varchar(10) not null);
db2 "insert into t1 with t (n) as (values 0 union all select n+1 from t where n+1 < 10000) select n, 2*n, 2*n+1 from t"
db2 "insert into t2 with t (n) as (values 0 union all select n+1 from t where n+1 < 10000) select 2*n, 'C' || rtrim(cast(2*n as char(10))) from t"
db2 runstats on table t1 with distribution and sampled detailed indexes all
db2 runstats on table t2 with distribution and sampled detailed indexes all
並檢查不同的查詢計劃。我添加了一個WHERE子句
兩個子選擇:
db2 "explain plan for SELECT stuff , (SELECT name FROM t2 WHERE id = sender_id) AS sender_name, (SELECT name FROM t2 WHERE id = recipient_id) AS recipient_name FROM t1 where t1.id between 500 and 600"
db2exfmt -d sample -g -1 -o sub.exfmt
兩個連接:
db2 "explain plan for SELECT t1.stuff, tA.name as sender_name, tB.name as recipient_name from t1 join t2 as tA on t1.sender_id = tA.id join t2 as tB on t1.sender_id = tB.id where t1.stuff between 500 and 600"
db2exfmt -d sample -g -1 -o dualjoin.exfmt
,最後用骨料和案例的變種:
db2 "explain plan for SELECT t1.stuff, max(case when t1.sender_id = t2.id then t2.name end) as sender_name, max(case when t1.recipient_id = t2.id then t2.name end) as recipint_name from t1 join t2 on t2.id in (t1.sender_id, t1.recipient_id) group by t1.stuff"
db2exfmt -d sample -g -1 -o singlejoin.exfmt
根據這一相當不科學的測試,@Juan Carlos Oropeza的解決方案是最便宜的:
Access Plan:
-----------
Total Cost: 132.657
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
101.808
^NLJOIN
( 2)
132.657
53
/-------+--------\
101.808 1
TBSCAN FETCH
( 3) ( 7)
13.6735 13.6215
2 2
| /---+----\
101.808 1 10000
SORT IXSCAN TABLE: LELLE
( 4) ( 8) T2
13.6733 6.81423 Q1
2 1
| |
101.808 10000
FETCH INDEX: SYSIBM
( 5) SQL150906110744470
13.6625 Q1
2
/---+----\
101.808 10000
IXSCAN TABLE: LELLE
( 6) T1
6.84113 Q2
1
|
10000
INDEX: SYSIBM
SQL150906110646160
Q2
在@ shA.t使用兩個子選擇的更多的是有點貴:
Access Plan:
-----------
Total Cost: 251.679
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
101.808
>^NLJOIN
( 2)
251.679
103.99
/-------+--------\
101.808 1
TBSCAN FETCH
( 3) ( 12)
132.695 13.6215
52.9898 2
| /---+----\
101.808 1 10000
SORT IXSCAN TABLE: LELLE
( 4) ( 13) T2
132.691 6.81423 Q1
52.9898 1
| |
101.808 10000
>^NLJOIN INDEX: SYSIBM
( 5) SQL150906110744470
132.67 Q1
52.9898
/-------+--------\
101.808 1
TBSCAN FETCH
( 6) ( 10)
13.6881 13.6215
2 2
| /---+----\
101.808 1 10000
SORT IXSCAN TABLE: LELLE
( 7) ( 11) T2
13.6839 6.81423 Q2
2 1
| |
101.808 10000
FETCH INDEX: SYSIBM
( 8) SQL150906110744470
13.6625 Q2
2
/---+----\
101.808 10000
IXSCAN TABLE: LELLE
( 9) T1
6.84113 Q3
1
|
10000
INDEX: SYSIBM
SQL150906110646160
Q3
我的解決方案是最昂貴的一個:
Access Plan:
-----------
Total Cost: 758.822
Query Degree: 1
Rows
RETURN
( 1)
Cost
I/O
|
10000
GRPBY
( 2)
758.139
124.996
|
20000
NLJOIN
( 3)
756.923
124.996
/----------+----------\
10000 2
FETCH FETCH
( 4) ( 6)
122.351 27.0171
49 3.96667
/---+----\ /---+----\
10000 10000 2 10000
IXSCAN TABLE: LELLE RIDSCN TABLE: LELLE
( 5) T1 ( 7) T2
58.1551 Q2 13.6291 Q1
21 2
| /-------+-------\
10000 1.0016 1.0016
INDEX: SYSIBM SORT SORT
SQL150906110646160 ( 8) ( 10)
Q2 6.81465 6.81465
1 1
| |
1.0016 1.0016
IXSCAN IXSCAN
( 9) ( 11)
6.81423 6.81423
1 1
| |
10000 10000
INDEX: SYSIBM INDEX: SYSIBM
SQL150906110744470 SQL150906110744470
Q1 Q1
對於那些RDBMS是這樣的?請添加相關標籤 - 謝謝 –
由於您想從中獲得兩個不同的結果 –