[pgsql-jp: 37052] Re: SELECTの性能
ISHIDA Akio
iakio @ mono-space.net
2006年 5月 16日 (火) 18:49:16 JST
こんにちは。石田@苫小牧市です。
ちょっと気になったのですが、元の SQL。
SELECT * FROM t1 LEFT JOIN t2 USING(f1) WHERE f2='xxx' AND f3=0 AND
t1.f4=false AND f5 IS NOT NULL ORDER BY f6 DESC LIMIT 300;
これは LEFT JOIN ではなく普通の JOIN で良いのではないでしょうか?
LEFT JOIN する意味としては、t1.f1 が t2.f1 に存在しない場合も
(t2.* を NULL として)行を返して欲しい、ということだと思いますが、
WHERE f2='xxx' してしまっているので、t2.f2 が NULL な行は
はじかれてしまいますよね。
普通の JOIN にするとプランがかわるかどうかはわかりませんが。
また、fukuda さんの SQL は元の SQL と同じ結果を返すので
しょうか。私は違うような気がするのですが。
06/05/16 に 河本陽一<komoto.yoichi @ kcc.co.jp> さんは書きました:
> こうもとです。
>
> fukuda さんの書いたこと:
> > select * from (select * from t1 where f3=0 and f4=false and f5 is not null) t1 left join (select * from t2 where f2 = 'xxx') t2 using (f1) order by f6 desc limit 300;
> > にすれば、副問いあわせ内でインデックスを使用した検索をさせることができるかと思いますが、
> > いかがでしょうか?
>
> この方法でもできました。
> EXPLAIN ANALYZEは以下のようになりました。
>
> Limit (cost=6.25..232.34 rows=300 width=255) (actual time=1.418..168.914 rows=300 loops=1)
> -> Nested Loop Left Join (cost=6.25..24011.29 rows=31853 width=255) (actual time=1.340..143.415 rows=300 loops=1)
> Join Filter: ("outer".f1 = "inner".f1)
> -> Index Scan Backward using t1_f6_idx on t1 (cost=0.00..21854.96 rows=31853 width=173) (actual time=0.060..13.834 rows=300 loops=1)
> Filter: ((f3 = 0) AND (f4 = false) AND (f5 IS NOT NULL))
> -> Materialize (cost=6.25..6.28 rows=3 width=86) (actual time=0.045..0.171 rows=3 loops=300)
> -> Seq Scan on t2 (cost=0.00..6.25 rows=3 width=86) (actual time=0.107..0.588 rows=3 loops=1)
> Filter: (f2 = 'xxx'::text)
> Total runtime: 182.084 ms
>
>
> 根岸さんの案の強制的にインデックスを使うやり方と同じくらいの性能の
> ようで、どちらを使用するか迷います。
> 福田さんの案の方が、正攻法っぽいのですが、処理内容的にはどちらがよ
> いのでしょうか。
> t2は、今後もそれほど増える予定はありません。
>
> ======================================================================
> 河本陽一(こうもとよういち)
> mailto:komoto.yoichi @ kcc.co.jp
>
>
--
ISHIDA Akio <iakio @ mono-space.net/ishida @ cycleof5th.com>
pgsql-jp メーリングリストの案内