以下のようなクエリーを作成して検索を
行っているのですが、どうしても抽出が出来ないくらい
遅くどの部分で遅くしているのかが分からないため、
どなたか教えてもらえないでしょうか?
※足りない情報があればすみませんが、仰ってください。
なるべくプログラム(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;
///////////////////////////////////////////
すみません何とか解決をしました。
odidにdistinct on (odid)とすると普通に
抽出できるようになりました。
ありがとう御座いました。
質問者
補足
以下が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)
お礼
すみません何とか解決をしました。 odidにdistinct on (odid)とすると普通に 抽出できるようになりました。 ありがとう御座いました。
補足
以下が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)