[pgsql-jp: 27180] Re: インデックスが使われない

tamagawa ryuji tamagawa @ sts.co.jp
2002年 8月 28日 (水) 15:30:58 JST


再度玉川です。こんな感じでどうでしょう?

SELECT TO_CHAR(最初のアクセス,'YYYY/MM/DD'), COUNT(ユーザー名)
FROM	(SELECT MIN(アクセス時刻) as 最初のアクセス, ユーザー名
	FROM Table T1
	WHERE アクセス時刻 BETWEEN 出力開始日 AND 出力終了日
	      AND NOT EXISTS (SELECT * FROM Table T2
				where T2.アクセス時刻 < 出力開始日
				      T1.ユーザー名=T2.ユーザー名 )
	GROUP BY ユーザー名) as t
GROUP BY TO_CHAR(最初のアクセス,'YYYY/MM/DD')
ORDER BY 1 DESC

キモになるのは、SELECT MIN(アクセス時刻) as 最初のアクセス, ユーザー名
をテーブル全体にかけず、まずは指定された期間に対してかけていることです。
ここでアクセス時刻のインデックスで絞り込めるはずです(ただし、全体に
対して指定期間が比較的短い場合だけかも)。

で、これだけだと指定期間内にアクセスがあり、なおかつ指定期間前にもアク
セスしてきているユーザーが紛れ込んでしまうので、not exists以下でこの
分を除外します。このときには、ユーザー名のインデックスを使ってくれる
のではないかと。もしかしたら、ユーザー名+アクセス時刻の複合インデックス
を作っておいた方がいいかもしれません。

--
玉川@STS

tamagawa ryuji wrote:
> 久々の書き込みです。玉川です。
> 
> 大まかな数字でかまいませんが、
> ・ユーザーは何人くらいで
> ・検索対象のテーブルには何件くらいのレコードがあって
> ・テーブル全体ではどのくらいの期間にわたってレコードが
>  あって
> ・検索対象になるのどのくらいの期間
> 
> なのでしょうか?このあたりの情報によっては、むしろ
> インデックスを使わない方が速いケースも出てくるはず
> です。
> 
> それと、
> 
> vaccumedb <データベース名> --analyze
> 
> はしてみましたか?これをやって、データの分布統計をとると
> アクセスパターンが変わることがありますよ。
> --
> 玉川@STS
> 
> みつき wrote:
> 
>>>「アクセス時刻」と「アクセス日」は違うものででしょうか。
>>
>>
>>同じものです。書き間違えました。
>>
>>
>>
>>>サブクエリ部分はテーブルの全件を対象としている
>>>ので、indexは使われないんじゃないでしょうか。
>>
>>
>>> 一度
>>>
>>>set enable_seqscan to 'OFF';
>>>
>>> を発行して強制的にindexを使用するようにして、速度を比較してみては
>>>どうでしょう。
>>
>>システム権限のせいで、試せませんでした。
>>
>>SQL部分をプログラムで置き換えてみて、
>>速度の違いを測ってみようと思います。
>>
>>結果が分かりましたら、発表したいと思います。
>>
>>みつき@
>>mitsuki @ zc5.so-net.ne.jp
>>
>>
> 
> 
> 
> 





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