为什么连接表的性能比加入子查询要快得多

时间:2017-01-31 20:26:17

标签: join subquery psql temp-tables

我想加入两个大表(711147和469519行)。但我只需要这些表的子集(44.593行和28.191行)。当我创建包含子集的临时表时,连接非常快(低于1秒)。当我使用子查询或视图时,需要5到10分钟。

问题是,每当我使用此查询时,子集(jahr = 2016)都已更改。所以使用“快速方式”,每次使用它时,我都必须先重新创建tmp表。问题是,这个查询本身是视图的基础,我不知道,当使用视图时。

临时表的快速方式如下:

select rechnung, art into temp rng16 from rng where jahr = 2016;
select rechnung, artikel, menge, epreis into temp fla16 from fla where jahr = 2016;
explain analyse select * from rng16 natural join fla16;

结果是:

Merge Join  (cost=4783.18..27406.15 rows=1500012 width=104) (actual time=544.691..679.280 rows=44593 loops=1)
   Merge Cond: (rng16.rechnung = fla16.rechnung)
   ->  Sort  (cost=1681.83..1714.72 rows=13158 width=64) (actual time=222.233..233.251 rows=27630 loops=1)
         Sort Key: rng16.rechnung
         Sort Method: external merge  Disk: 520kB
         ->  Seq Scan on rng16  (cost=0.00..284.58 rows=13158 width=64) (actual time=0.009..2.880 rows=28191 loops=1)
   ->  Materialize  (cost=3101.35..3215.35 rows=22800 width=72) (actual time=322.449..362.445 rows=44593 loops=1)
         ->  Sort  (cost=3101.35..3158.35 rows=22800 width=72) (actual time=322.444..356.178 rows=44593 loops=1)
               Sort Key: fla16.rechnung
               Sort Method: external merge  Disk: 1248kB
               ->  Seq Scan on fla16  (cost=0.00..513.00 rows=22800 width=72) (actual time=0.008..7.832 rows=44593 loops=1)
 Total runtime: 682.589 ms

但使用两个子查询“即时”执行此操作

explain analyse select * from (select rechnung, art from rng where jahr=2016) rng16 natural join (select rechnung, artikel, menge, epreis from fla where jahr = 2016) fla16; 

持续多年。解释的输出是:

Nested Loop  (cost=0.85..10.98 rows=1 width=21) (actual time=0.036..453240.711 rows=44593 loops=1)
   Join Filter: (rng.rechnung = fla.rechnung)
   Rows Removed by Join Filter: 1257076670
   ->  Index Scan using rng_jahr on rng  (cost=0.42..5.51 rows=1 width=9) (actual time=0.017..54.372 rows=28191 loops=1)
         Index Cond: (jahr = 2016)
   ->  Index Scan using fla_jahr on fla  (cost=0.42..5.46 rows=1 width=19) (actual time=0.020..9.875 rows=44593 loops=28191)
         Index Cond: (jahr = 2016)
 Total runtime: 453253.579 ms

1 个答案:

答案 0 :(得分:0)

尝试连接表,而不是使用子查询,如下所示:

explain analyse 

select 
    rng16.rechnung, rng16.art 
    fla.rechnung, fla.artikel, fla.menge, flaepreis
from 
    rng rng16 
natural join 
    fla
where 
    rng16.jahr = 2016
    and fla.jahr = 2016

它仍然是嵌套循环吗?