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

kato carrot-s @ agate.plala.or.jp
2014年 9月 2日 (火) 21:11:00 JST


佐藤様

加藤です。お世話になっております。

ご回答ありがとうございます。
ご連絡が遅くなりまして申し訳ありません。

>Subquery Scan は副問い合わせの結果をスキャンする処理を行います。
>
>単に行数が多い (2300 万行) ので時間がかかっているのだと思います。
>すでに共有バッファからデータを読み取っており、Subquery Scan のみで
>どうにかするのは難しいと思います。

上記、結合までの処理で SharedBuffer にデータが載っている状態で
さらにスキャンをしている、と理解しました。
無駄な処理のように思えてしまうのですが、そういうものなのでしょうか。

それとも、結合処理時点では結合条件の部分以外はスキャンされておらず、
最終的にサブクエリの結果を得るにはあらためてスキャンする必要がある
というようなことでしょうか?


>はじめに SQL や実行計画の全体を知りたかったのは、
>全体の実行時間においてSubquery Scan がどのくらいを占めているのか、
>ほかに何かやれるべきことはないかを見たかったからです。

なるほど、ありがとうございます。
実行計画だけであれば、(ほぼ)そのままのものを提示できるかもしれません。
その際はまたアドバイスをいただければ幸いです。


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

(2014/09/02 0:28), Tomoaki Sato wrote:
> 佐藤です。
>
> From: kato <carrot-s @ agate.plala.or.jp>
> Date: Fri, 29 Aug 2014 22:02:25 +0900
>
>> ご回答ありがとうございます。
>>
>> PostgreSQLのバージョンは、9.3.1でした。失礼いたしました。
>>
>> SQLそのものは都合により提示できかねるため、
>> このような内容にてご質問させて頂いた次第です。
>> (せっかくご助言頂いたのに、すみません)
>>
>> 質問内容が実行計画の読み方、という点で
>> 汎用的な内容のため、このような内容でも何か見解を
>> 頂けるかも知れないと考えたのですが、やはり厳しいですかね。。。
> もとの質問への答えとしては
>
>>>> 上記、[3]が 15061.768ms で完了した後、[1]のSubquery Scanで
>>>> 30795.488ms までかかっている認識です。
>>>> 結合処理自体は[3]で終わっていると考えているのですが、
>>>> [3]→[1]の間ではどのような処理が行われ、時間がかかっているのか?
>>>> また、その処理のパフォーマンスを改善する方法があるのか?
>>>> ご存知の方がいらっしゃいましたら、ご教示いただければ幸いです。
> Subquery Scan は副問い合わせの結果をスキャンする処理を行います。
>
> 単に行数が多い (2300 万行) ので時間がかかっているのだと思います。すでに
> 共有バッファからデータを読み取っており、Subquery Scan のみでどうにかす
> るのは難しいと思います。
>
> はじめに SQL や実行計画の全体を知りたかったのは、全体の実行時間において
> Subquery Scan がどのくらいを占めているのか、ほかに何かやれるべきことは
> ないかを見たかったからです。
>
>> (2014/08/28 19:53), Tomoaki Sato wrote:
>>> 佐藤です。
>>>
>>>> 加藤と申します。
>>>> はじめて利用させていただきます。よろしくお願い致します。
>>>>
>>>> 以下のようなSQLのパフォーマンスを改善しようとしています。
>>>> (便宜上、左端に番号を振っています)
>>> SQL は省略せずに実行できるもの、実行計画も抜粋ではなく出力されたそのま
>>> まを出してくれれば、力になってくれる人がいるかもしれません。
>>>
>>> あと、
>>>
>>>> ------------------------------------
>>>> OS:RHEL6.4
>>>> PostgreSQL Version:9.4.1
>>>> ------------------------------------
>>> 9.4 はまだリリースされていないので 8.4.1 の間違いですかね。
>>>
>>>> 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
>>>> ------------------------------------
>
> ----
> Tomoaki Sato <sato @ sraoss.co.jp>
> SRA OSS, Inc. Japan
>
>



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