アプリ版:「スタンプのみでお礼する」機能のリリースについて

以下のようなクエリーを作成して検索を
行っているのですが、どうしても抽出が出来ないくらい
遅くどの部分で遅くしているのかが分からないため、
どなたか教えてもらえないでしょうか?
※足りない情報があればすみませんが、仰ってください。

なるべくプログラム(PHP等)を使わずクエリのみで
行いたいので、PHP云々の話しは無しでお願い致します。

最初の抽出テーブル(osi)と次の抽出テーブル(osday)
をそれぞれ個別で動かすと普通の速度で抽出が旨く行きます
が、それらをくっつけた形
select (省略) from osi,osday where osi.id=osday.id;
とすると、抽出が行えない又は非常に遅いとなります。

///////// 実際のクエリー文です /////////
select osday.odid,odctmid,saitemname,startday,endday from
(
select
odid,saitemname
from order1 as o,sale as s
where o.odid=s.saorderid
and (o.odshipdue >= '2007-12-1 00:00:00' and o.odshipdue <= '2007-12-18 23:59:59')
and (o.odcancelflag='0' or o.odcancelflag is null)
and o.odclass<'4' and s.saregular='1'
and s.saitemcode in (select itcode from item where itcategory='1')
and odmakeday is not null
) osi
,
(
select
odid,max(odctmid) as odctmid,to_char(min(o.odshipday), 'YYYY-MM-DD') as startday,to_char(max(o.odshipday), 'YYYY-MM-DD') as endday
from order1 as o,sale as s
where o.odid=s.saorderid
and (o.odshipdue >= '2007-12-1 00:00:00' and o.odshipdue <= '2007-12-18 23:59:59')
and (o.odcancelflag='0' or o.odcancelflag is null)
and o.odclass<'4' and s.saregular='1'
and s.saitemcode in (select itcode from item where itcategory='1')
and odmakeday is not null group by o.odid
) osday
where osi.odid=osday.odid;
///////////////////////////////////////////

A 回答 (1件)

とりあえずpostgreSQLでしたら発行するSQL文の頭にexplainを付けて、QUERY COSTを確認してみてはいかがでしょうか?


cost=の数字が極端に大きくなるところが律速です。

この回答への補足

以下がexplainを行った結果になります。
どうも”ソート”で非常に時間がかかっている事は
分かるのですが、どこをどう変更を行うと
早くする事が可能なのかが分かりませんので、
申し訳ないのですが、お教え願いますでしょうか?

Merge Join (cost=3540286937523.30..7081061083958.06 rows=40538736678 width=185)
Merge Cond: ("outer".odid = "inner".odid)
-> Nested Loop (cost=0.00..3540266237821.62 rows=389823931 width=109)
Join Filter: ((("outer".odcancelflag = 0) AND ("outer".odid = "inner".saorderid) AND ("outer".odshipdue >= '2007-12-01 00:00:00+09'::timestamp with time zone) AND ("outer".odshipdue <= '2007-12-18 23:59:59+09'::timestamp with time zone) AND ("outer".odclass < 4::bigint)) OR (("outer".odcancelflag IS NULL) AND ("outer".odid = "inner".saorderid) AND ("outer".odshipdue >= '2007-12-01 00:00:00+09'::timestamp with time zone) AND ("outer".odshipdue <= '2007-12-18 23:59:59+09'::timestamp with time zone) AND ("outer".odclass < 4::bigint)) OR (("inner".saregular = '1'::character varying) AND (subplan) AND ("outer".odmakeday IS NOT NULL)))
-> Index Scan using order1_pkey on order1 o (cost=0.00..1444665.32 rows=374858 width=32)
-> Seq Scan on sale s (cost=0.00..11803.60 rows=418060 width=77)
SubPlan
-> Materialize (cost=22.50..22.55 rows=5 width=32)
-> Seq Scan on item (cost=0.00..22.50 rows=5 width=32)
Filter: (itcategory = 1::bigint)
-> Sort (cost=3540289316823.30..3540289414279.28 rows=38982393 width=93)
Sort Key: osday.odid
-> Subquery Scan osday (cost=0.00..3540270136060.93 rows=38982393 width=93)
-> Aggregate (cost=0.00..3540270136060.93 rows=38982393 width=93)
-> Group (cost=0.00..3540267212381.45 rows=389823931 width=93)
-> Nested Loop (cost=0.00..3540266237821.62 rows=389823931 width=93)
Join Filter: ((("outer".odcancelflag = 0) AND ("outer".odid = "inner".saorderid) AND ("outer".odshipdue >= '2007-12-01 00:00:00+09'::timestamp with time zone) AND ("outer".odshipdue <= '2007-12-18 23:59:59+09'::timestamp with time zone) AND ("outer".odclass < 4::bigint)) OR (("outer".odcancelflag IS NULL) AND ("outer".odid = "inner".saorderid) AND ("outer".odshipdue >= '2007-12-01 00:00:00+09'::timestamp with time zone) AND ("outer".odshipdue <= '2007-12-18 23:59:59+09'::timestamp with time zone) AND ("outer".odclass < 4::bigint)) OR (("inner".saregular = '1'::character varying) AND (subplan) AND ("outer".odmakeday IS NOT NULL)))
-> Index Scan using order1_pkey on order1 o (cost=0.00..1444665.32 rows=374858 width=48)
-> Seq Scan on sale s (cost=0.00..11803.60 rows=418060 width=45)
SubPlan
-> Materialize (cost=22.50..22.55 rows=5 width=32)
-> Seq Scan on item (cost=0.00..22.50 rows=5 width=32)
Filter: (itcategory = 1::bigint)

補足日時:2007/12/19 16:17
    • good
    • 0
この回答へのお礼

すみません何とか解決をしました。
odidにdistinct on (odid)とすると普通に
抽出できるようになりました。

ありがとう御座いました。

お礼日時:2007/12/19 18:30

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!