[pgsql-jp: 41712] union all時のSubquery Scanの処理内容とパフォーマンス改善について

kato carrot-s @ agate.plala.or.jp
2014年 8月 27日 (水) 18:16:22 JST


加藤と申します。
はじめて利用させていただきます。よろしくお願い致します。

以下のようなSQLのパフォーマンスを改善しようとしています。
(便宜上、左端に番号を振っています)


01 select ... from
02 (
03 (
04 select aaa
05 ,...
06 from tableA
07 left outer join tableB1
08 on (...)
09 left outer join tableC1
10 on (...)
11 where tableA.num2 = 0
12 and ...
13 )
14 union all
15 (
16 select aaa
17 ,...
18 from tableA
19 left outer join tableB2
20 on (...)
21 left outer join tableC2
22 on (...)
23 where tableA.num2 <> 0
24 and ...
25 )
26 ) as t
27 group by ...
28 order by ...


#<補足>
#実際は、union all の上と下それぞれ、もっとたくさんの
#テーブルとleft outer joinしていますが、割愛しています。
#また、テーブル tableAはパーティション化しています。


上記のSQLにexplain (analyze on, buffers on)をつけて
実行した結果、上記番号12〜の部分で以下のような実行計画となりました。

以下、番号12〜の部分を抜粋します。(こちらも左端に番号[1]...をふっています)


[1] ->Subquery Scan on "*SELECT* 2" (cost=7583.21.481866.70 rows=2172792
b.width=1092) (actual time=227.093..30795.488 rows=2304000 loops=1)
[2] Buffers: shared hit=50915
[3] ->Hash Left Join (cost=7583.21..460138.78 rows=2172792 width=1092)
(actual time=227.056..15061.768 rows=2304000 loops=1)
[4] Hash Cond: ((tableA_4.num1=tableC2.num1) AND
(tableA_4.num2=tableC2.num2))
[5] Buffers: shared hit=50915
[6] ->Hash Left Join (cost=7559.71.405795.48 rows=2172792 width=1082)
(actual time=226.747..9133.426 rows=2304000 loops=1)
[7] Hash Cond: ((tableA_4.num1=tableB2.num1) AND
((tableA_4.text1)::text=(tableB2.text1)::text))
[8] Buffers: shared hit=50908
[9] ...



上記、[3]が 15061.768ms で完了した後、[1]のSubquery Scanで
30795.488ms までかかっている認識です。
結合処理自体は[3]で終わっていると考えているのですが、
[3]→[1]の間ではどのような処理が行われ、時間がかかっているのか?
また、その処理のパフォーマンスを改善する方法があるのか?
ご存知の方がいらっしゃいましたら、ご教示いただければ幸いです。


------------------------------------
OS:RHEL6.4
PostgreSQL Version:9.4.1
------------------------------------


よろしくお願い致します。
以上



pgsql-jp メーリングリストの案内