抽出が出来ないくらい遅いクエリ

このQ&Aのポイント
  • クエリの速度が非常に遅く、抽出ができない問題について
  • osdayテーブルとosiテーブルを結合したクエリの速度が遅い
  • クエリの最適化を行いたいが、どの部分が遅いのかが分からない
回答を見る
  • ベストアンサー

抽出が出来ないくらい遅いクエリ

以下のようなクエリーを作成して検索を 行っているのですが、どうしても抽出が出来ないくらい 遅くどの部分で遅くしているのかが分からないため、 どなたか教えてもらえないでしょうか? ※足りない情報があればすみませんが、仰ってください。 なるべくプログラム(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; ///////////////////////////////////////////

質問者が選んだベストアンサー

  • ベストアンサー
  • miya_0726
  • ベストアンサー率54% (94/173)
回答No.1

とりあえずpostgreSQLでしたら発行するSQL文の頭にexplainを付けて、QUERY COSTを確認してみてはいかがでしょうか? cost=の数字が極端に大きくなるところが律速です。

unhork
質問者

お礼

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

unhork
質問者

補足

以下が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)

関連するQ&A

  • ACCESS2000でクエリを抽出条件で抽出

    VBA上でクエリの抽出データを取得してファイルに書き込むというプログラムを書いております。 抽出条件として、今日の日付のレコードを取得したいのですが型が一致しませんとエラーになります。 strSQL = "SELECT * FROM " & (クエリー名)& " where (クエリー.カラム名)='" & Format(Date, "yyyy/mm/dd") & "'" クエリーのカラム名は全角漢字です。 どこがおかしいのでしょうか? よろしくお願いいたします。

  • 日時の期間での抽出

    スケジュール帳のWebアプリを作成していて PostgreSQLを使用しています。 sc_tblというテーブルのday_timeというカラムに日時 to_doというカラムに予定を入れているのですが 日時2006/12/01 01:00のデータを期間の抽出条件で抽出する時 2006/11/30 20:00~2006/11/30 26:00という条件で抽出できるような SQL文はあるのでしょうか。(1:00を25:00として抽出したい) 下記2つのSQLでは無理でした。 ・その1 select day_time, to_do from sc_tbl where day_time >= cast('2006-11-30 20:00:00' as timestamp) and day_time <= cast('2006-11-30 26:00:00' as timestamp); ・その2 select day_time, to_do from sc_tbl where day_time >= to_date('2006-11-30 20:00:00','YYYY-MM-DD H24:MI:SS') and day_time <= to_date('2006-11-30 26:00:00','YYYY-MM-DD H24:MI:SS');

  • AccessのクエリでvbLfのみ抽出するには

    Access2010のクエリー(SQL)で vbLfかvbCrLfが含まれているレコードを抽出するには、 SELECT [テーブル1].* FROM テーブル1 WHERE [テーブル1].フィールド1 Like "*" & Chr(10) & "*"; vbLfが含まれているレコードは抽出せず、 vbCrLfが含まれているレコードだけを抽出するには、 SELECT [テーブル1].* FROM テーブル1 WHERE [テーブル1].フィールド1 Like "*" & Chr(13) & Chr(10) & "*"; でよいと思いますが、 vbCrLfが含まれているレコードは抽出せず、 vbLfが含まれているレコードだけを抽出するには、 どのように記述すればよいのでしょうか。 よろしくお願いします。

  • 指定した値の範囲内の列を抽出

    Access2000を使用 前回答えてもらったとおり指定した1つの値からはデータの抽出成功しました。 で今回も同じような内容で、指定した値(月初から今日の日付)までの値を抽出するようなSQL文がわかりません。 以下はwhere以降で、BETWEENを使用しましたが抽出できませんでした。 他の方法はございますか? where (クエリー名.クエリーカラム名) BETWEEN #" & Format(Date - mday + 1, "yyyy/mm/dd") & "# AND #" & Format(Date, "yyyy/mm/dd") & "#" よろしくお願いします。

  • グループ毎の条件抽出

    はじめまして。よろしくお願いします。 今、以下のようなデータで以下の抽出条件でデータ取得行いたいと思っています。 ■ TABLEA NO 1~n 識別 A~Z 状況 1~4(null有り) 日付 YYYY/MM/DD 1.識別毎にグループ分けをしたい。 2.「1.」の中で状況が最大値の物のみ抽出 3.「2.」の中で日付が最大値の物のみ抽出 4.識別が無いものは各行出力 5.「1.~3.」の中で抽出されたデータのTABLEAのカラムを全て取得 今は以下のようなSQLで実現させようとしておりますが、 インラインビューを何度もネストしている為あまりパフォーマンスが 良くないです。もっと効率的なSQLが在れば教えていたければと思います。 SELECT /* 4.対象TABLEAのデータを取得 */ * FROM TABLEA, /* 2.グループの中で日付日付の最大値を求める */ (SELECT MAX(TABLEA.日付) AS 最新日付, TABLEA.状況 TABLEA.識別 FROM TABLEA, /* 1.識別毎に状況の最大値を求めるグループ */ ( SELECT MAX(状況) AS 状況最大値, 識別 FROM TABLEA WHERE 識別 IS NOT NULL GROUP BY 識別 )TMP WHERE TABLEA.識別 = TMP.識別 TABLEA.状況 = TMP.状況最大値 )TMP2 TABLEA.日付 = TMP2.最新日付 TABLEA.状況 = TMP2.状況 TABLEA.識別 = TMP2.識別 /* 3.識別は無いものを取得 */ UNION SELECT * FROM TABLEA WHERE 識別 IS NULL 以上です。よろしくお願いします。

  • 不一致クエリでnullまで抽出されてしまいます

    質問です。 現在、accessにて不一致クエリを使用し、テーブルAをチェックし、 マスタテーブルに無い情報が書かれてしまっているフィールドがある場合 抽出して確認をする、というクエリを作りたいと考えています。 不一致クエリにて自動で入る「is null」を使用すると マスタテーブルに無い事が書いてあるレコードは抽出するのですが (逆になぜis nullで相違するレコードが抽出されるのか理解に苦しんでもいるのですが) is nullですので、nullのレコードも抽出されてしまいます。 抽出条件として、マスタテーブルと相違するもの&nullは抽出しない、としたいのですがお知恵を拝借出来ませんでしょうか。 よろしくお願いいたします。

  • アクセスクエリ ハテナを抽出するには

    テーブルは 文字(フィールド) ? あ となっていて、 クエリで SELECT [テーブル1].文字 FROM テーブル1 WHERE ((([テーブル1].文字) Like "?")); とすると、 ? あ が抽出されます。 ?がワイルドカードとなり、1文字の文字列を抽出する、という条件になってしまったためだと思われますが、ワイルドカードではなく、ハテナとして抽出したい場合はどうすればいいでしょうか? エクセルのように、Like "~?"としたら、何も抽出されませんでした。

  • テーブルで使用するinについて

    select count(r.テスト1) as all_count from DB1 as r where 1=1 and ( r.テスト1 in (select distinct テスト1 from DB2 where テスト1 is not null and テスト2 is not null)); このようなSQL文がある場合は どのような意味になるのでしょうか? inといものはどのようなときに使うのでしょうか? ご教授お願いいたします。

  • クエリの抽出条件で困っています

    Access2007にて、クエリの抽出条件に下記を指定していますが、データが1件も抽出されません。 ※エラーは表示されません IIf([forms]![F_Home]![アンケート種別]="1級",1 Or Is Null,2 Or Is Null) この抽出条件をしているフォールドには"1"、"2"、nullのデータしか存在しません。 「アンケート種別」が"1級"の場合は、"1"とnullのデータをかえし、 それ以外の「アンケート種別」の場合は、"2"とnullのデータをかえしたいと思っています。 どのように条件を指定すれば、データを抽出できるようになるでしょうか。 宜しくお願い致します。

  • クエリの遅さの原因

    下記のクエリーをそれぞれ試してみたところ、圧倒的に下の方が遅くなってしまいました。 $rs = mysql_query("select * from A INNER JOIN B ON B.cat = A.id order by B.id desc LIMIT 1, 10 ;",$con); $rs = mysql_query("select * from A INNER JOIN B ON B.cat = A.id where B.name is not null group by B.area order by B.id desc LIMIT 1, 10 ;",$con); where B.name is not null group by B.area この処理はそれほど負荷が掛かってしまうのでしょうか。 他に良い書き方(方法)がありましたら教えてください。

    • ベストアンサー
    • MySQL