2017-03-07 44 views
0

我有這樣的說法:性能問題聲明

select qulified_name 
from table 
inner join references_table on references_table.id = table.ref_id 
where references_table.type = 'x' and table.value in (... +110 000 ids) 

這是緩慢的極端。 (網絡應用程序崩潰並且沒有得到結果 我在rom-rb的幫助下創建了我的聲明並使用了續集,但是這是當我查看聲明時得到的聲明

如果我重寫這樣的保護 - 諮詢熱點相比第一個版本的表現真的很不錯:

select qulified_name 
from table 
inner join (select unnest(array['#{references_id.join("','")}']) id) as tmp on tmp.id = businesspartner_references.value 
inner join references_table on references_table.id = table.ref_id 
where references_table.type = 'x' 

這樣,我得到的結果〜3秒

誰能給我解釋一下爲什麼是這樣的情況。 ?我不明白..

+0

嘗試使用'explain'運行兩者 - 我猜臨時表的連接速度比in子句的掃描速度快很多 – paqash

+0

您使用的是哪個版本的rom-rb? – solnic

+0

@solnic rom3.1.0,rom-repository 1.2.0和rom-sql 1.1.1但是來自karthik的回答對我來說足夠了。謝謝! – Shimu

回答

2

當您使用IN子句時,尤其是有大量值的情況下,數據庫別無選擇,只能迭代地比較每個元組值和IN子句中的每個值,這將效率低下。

相反,當您使用子查詢將其轉換爲派生表時,它現在變成了面向集合的連接操作,相反,它是集合操作。

數據庫非常擅長評估面向集合的操作,並且可以爲您的數據找到最佳的連接算法。