2016-09-06 69 views
0

我有這樣一個查詢:優化多個子查詢與子句中的Oracle

select 
    qsn.code, 
    (select prs.display_name from prs where prs.id = qsn.fk_prs) display_name, 
    (select prs.address from prs where prs.id = qsn.fk_prs) address, 
    (select prs.tel from prs where prs.id = qsn.fk_prs) tel 
from 
    qsn 
where 
    qsn.register_date between :x1 and :x2 

當我看到查詢的執行計劃,它查詢prs表3倍(使用INDEX UNIQUE SCAN每次)。

我不知道是否可以查詢一次使用WITH子句prs表?我如何以這種方式編寫查詢。

我會提到,因爲每個表都有數百萬條記錄,所以加入它們會使查詢速度變慢。

+0

沒有看到你的執行計劃,只有瘋狂的猜測是可能的。請爲這兩個查詢發佈[執行計劃](http://stackoverflow.com/questions/34975406/how-to-describe-performance-issue-in-relational-database?answertab=active#tab-top)(使用子查詢和加入)。你的觀察的一個解釋是你切換到散列連接(在兩個表上都有可能的FTS),另一種解釋是你從標量子查詢兌現中獲利(如果'qsn.fk_prs'的數目相對較少)。 –

回答

1

與條款您的查詢是這樣的:

with abc as (select id, 
        display_name , 
        address , 
        tel 
       from prs) 
select 
    qsn.code, 
    abc.display_name, 
    abc.address, 
    abc.tel 
from qsn 
inner join abc 
on qsn.fk_prs = abc.id 
where qsn.register_date between :x1 and :x2 ; 

PS:未測試。

1

使用連接:使用

select qsn.code, prs.display_name, prs.address, prs.tel 
from qsn 
left join prs on prs.id = qsn.fk_prs 
where qsn.register_date between :x1 and :x2 
+0

正如我在加入他們時所提到的,查詢執行時間變得更糟! –

+0

@AmirPashazadeh - 你有'qsn.fk_prs'上的索引,而不僅僅是'prs.id'嗎?如果你不這樣做,請添加一個,看看是否有幫助。 – mathguy

+0

是的它有索引,但沒有'id','display_name','address'和'tel'組合的索引。我總是使用ANSI連接,但查詢成本(使用解釋計劃從41000增加到64000) –