簡體   English   中英

如何優化條件連接的查詢?

[英]how to optimize query with conditional join?

我需要優化查詢,其中聯接取決於條件

我有兩張桌子

Table1有兩列,可以將它們稱為A和B列,它們可以與table2列C有關,

如果列B為空,則必須將t1.A與t2.C匹配如果列B不為空,則必須將t1.B與t2.C匹配

最后我需要知道t1上的哪些條目在t2上不匹配...

更詳細地說,t1是客戶表,而A和B都是客戶代碼。 A代碼永遠不會與B代碼相同,並且在存在B的情況下,B具有優先權(B是新的客戶代碼,而舊客戶則沒有)。在B為空的情況下,A是代碼使用)(所有這些都是因為B列是新列,而舊客戶端的B值為空)。

t2是購買表。 t2.C是客戶端代碼,但是在這種情況下是單個列,它存儲舊客戶端的A代碼和新客戶端的B代碼。

我唯一想做的就是知道哪個客戶還沒有購買商品,並盡可能高效地進行查詢。

我提出了幾個查詢,但是由於條件的處理方式,它們非常慢,我想:

第一次嘗試:

select * 
from t1
left join t2 on (t1.A = t2.C or t1.B = t2.C)
where t2.D is null;

請注意,我可以使用OR條件,因為我知道t1.A永遠不會與任何t1.B相同,因此在t2.C中,它僅與A或B匹配,但絕不會與兩者匹配(假定條件是保證)。 查詢是如此緩慢,以至於在我的sql客戶端中超時。

第二次嘗試

select * 
from t1
left join t2 on (if(t1.B is null, t1.A = t2.C, t1.B = t2.C))
where t2.D is null;

在這種情況下,比較條件取決於t1.B,如果為null,則與A進行比較,如果不為B,則與B進行比較。同樣,查詢非常慢。

我想我可以只使用兩個聯接,並為每個聯接使用每個條件(A或B),但是我不知道如何實現它,特別是因為我只需要獲得A o B都沒有的情況t2比賽。 (即,沒有t2購買的t1客戶)

在這種情況下,如何建立更有效的查詢?

謝謝

如果您在t1.At1.B上沒有索引,那么我懷疑IFNULL將是您最好的選擇:

select * 
from t1
left join t2 on ifnull(t1.B, t1.A) = t2.C
where t2.D is null;

但是,如果對任一列都建立了索引,我懷疑您可以通過使用UNION ALL來獲得最佳性能:

select * 
from t1
left join t2 on t1.A = t2.C
where t2.D is null
and t1.B is null
union all
select * 
from t1
left join t2 on t1.B = t2.C
where t2.D is null
and t1.B is not null;

原因是在編譯過程中,優化器將不知道是否對連接使用t1.At1.B ,因此無法選擇索引,而是選擇表掃描,但是如果將其分為兩個查詢,它將知道哪個要在聯接上使用的列,並且可以使用適當的索引。

SQL小提琴示例

las,執行條件聯接往往會導致非常差的查詢性能。 在這種情況下,您正在測試兩個值,並且大概正在尋找是否都不存在。 嘗試將其分為兩個聯接:

select * 
from t1 left join
     t2
     on t1.A = t2.C left join
     t2 t2a
     on t1.B = t2a.C
where t2.D is null and t2a.D is null;

這將允許查詢使用A,B和C上的索引。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM