2017-01-04 48 views
0

我試圖做這樣的事情:慢INNER JOIN與多個手術室

SELECT attr1, attr2, attr3, ... 
FROM table1 t1 
INNER JOIN table2 t2 ON (
    (t1.a = t2.a OR t1.b = t2.b OR t1.c = t2.c) AND 
    (t1.d = t2.d OR t1.e = t2.e OR t1.f = t2.f) 

此查詢具有性能非常差,沒有在ON子句中的列都的PK。什麼是改進此查詢的好替代方案?

+0

沒有表統計和執行計劃,這將是不切實際的地址。所以我的猜測是't1.a = t2.a時的情況,當t1.b = t2.b時爲1 ,t1.c = t2.c時爲1 ,然後是1 否則0結束+ 當t1時。 d = t2.d然後1 當t1.e = t2.e然後1 當t1.f = t2.f然後1 end = 2' – xQbert

+0

您沒有向我們展示表/索引的結構,解釋查詢計劃也不(如xQbert提及)數據基數/分佈的統計數據。該查詢表明你的模式沒有被標準化。 – symcbean

+0

不要使用a,b,c ......進行混淆,請給我們一個關於這是什麼應用程序的線索 - 也許是通過使用真實的列名稱。 _may_是一種解決方法,與給你麻煩的表述完全不同。 –

回答

3

這會很慢。更快的方法是多個left join S:

select t1.*, t2.?, t3.?, t4.? . . 
from t1 left join 
    t2 t2a 
    on t1.a = t2a.a left join 
    t2 t2b 
    on t1.b = t2b.b left join 
    . . . 
where t2a.a is not null or t2b.b is not null or t2c.c is not null or . . . 

這可以在t2(a)t2(b)採取的單獨索引優點,等等。

請注意,結果集有點不同。假設每列支付最多一個匹配,您將獲得一個輸出行上給定行的所有匹配。

+0

@ spencer7593。 。 。 where子句要求至少有一個匹配。 –

0

另一種選擇是創建一個查詢每個連接組合(其中9人)和聯合在一起:

SELECT attr1, attr2, attr3, ... 
FROM table1 t1 
INNER JOIN table2 t2 ON 
    (t1.a = t2.a) AND 
    (t1.d = t2.d) 

UNION 

SELECT attr1, attr2, attr3, ... 
FROM table1 t1 
INNER JOIN table2 t2 ON 
    (t1.a = t2.a) AND 
    (t1.e = t2.e) 
UNION 

... 

UNION 

SELECT attr1, attr2, attr3, ... 
FROM table1 t1 
INNER JOIN table2 t2 ON 
    (t1.c = t2.c) AND 
    (t1.f = t2.f) 

這種方式,你可以創建在每一列對一個綜合指數。 (A,D),(A,E)...(C,F)