2016-09-06 66 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) –