VIEWのレスポンス改善について

このQ&Aのポイント
  • オラクル10gでのレスポンス改善について勉強中です。MASTER_CODEテーブルを使用してVIEWを作成しましたが、SQLの書き方に問題があります。マスターを参照する際、コードではなく名称で取得できるVIEWを作成したいと考えています。
  • トランザクションテーブルからマスターを参照するため、MASTER_CODEテーブルから特定の区分とレベルでコードと名称を取得しています。しかし、この方法ではレスポンスが悪くなることがあります。
  • 同じMASTER_CODEを使用しているので、より効果的な方法があるか教えてください。目標は、コードではなく名称で取得できるVIEWを作成することです。
回答を見る
  • ベストアンサー

VIEWのレスポンス改善について

現在オラクル10gでレスポンス改善の勉強をしています。 下記のようなデータ、テーブルがあるとき有効なSQLの書き方が分かりません。 テーブル名;MASTER_CODE カラム名 ・区分コード ・コード ・レベル ・名称 サンプルデータ 区分コード、コード、レベル、名称 1000 10 1 東京本部 1000 11 1 大阪支店 1000 12 1 福岡支店 1000 10 2 営業部  1000 11 2 開発部 1000 12 2 総務部 1000 10 3 1課 1000 11 3 2課 1000 12 3 3課 1100 10 1 A商事 1100 11 1 B商事 1100 12 1 C商事 1100 10 2 A商事の住所 1100 11 2 B商事の住所 1100 12 2 C商事の住所 テーブル名;TRAN_TABLE カラム名 ・連番 ・支店コード ・部署コード ・課コード ・得意先コード ・得意先住所コード サンプルデータ 連番、支店コード、部署コード、課コード、得意先コード、得意先住所コード 1 10 12 10 10 10 2 11 11 12 11 11 3 12 10 11 12 12 上記のようなテーブルがあり トランザクショテーブルからマスタを参照し、 コードではなく名称で取得できるVIEWを作成しました。 select * from TRAN_TABLE A, (select コード、名称 from MASTER_CODE where 区分=1000 AND レベル=1) SHITEN, (select コード、名称 from MASTER_CODE where 区分=1000 AND レベル=2) BUSHO, (select コード、名称 from MASTER_CODE where 区分=1000 AND レベル=3) KA, (select コード、名称 from MASTER_CODE where 区分=1100 AND レベル=1) TORIHIKISAKI, (select コード、名称 from MASTER_CODE where 区分=1100 AND レベル=2) TORIJUSHO WHERE SHITEN.コード(+)=A.支店コード AND BUSHO.コード(+)=A.部署コード AND KA.コード(+)=A.課コード AND TORIHIKISAKI.コード(+)=A.得意先コード AND TORIJUSHO.コード(+)=A.得意先住所コード  上記のSQLだとレスポンスがよくありません。 (実際はマスターテーブルに多くのデータを登録してあります) 同じMASTER_CODEを使用しているので、もっと良い方法があるのでしょうか? ご回答宜しくお願いします。

  • Oracle
  • 回答数1
  • ありがとう数1

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

  • ベストアンサー
  • uresiiwa
  • ベストアンサー率45% (49/107)
回答No.1

このSQL内容であれば、以下のようにスカラー副問い合わせ(SELECT文の中に入っている、単行を返すSELECT文)を使うのがベストだと思います。また、もしマスタに「区分+レベル+コード」のインデックスがなければ追加してください。 スカラー副問い合わせはマスタから名称を取るような場合に最適な方法のため、元SQLがうまく最適化されていれば同等のパフォーマンスとなる可能性もありますが、良くなることはあっても悪くなることはない書き方になります。(今回の場合。) 厳密な比較のためには、元SQLと実行計画やSQLトレースを比較してみてください。 (インデックスのほうが原因という可能性もありますね。) ------------------------------------------------------------------ select A.連番 , A.支店コード , A.部署コード , A.課コード , A.得意先コード , A.得意先住所コード , (select 名称 from MASTER_CODE where 区分=1000 AND レベル=1 AND コード = A.支店コード) AS "支店名" , (select 名称 from MASTER_CODE where 区分=1000 AND レベル=2 AND コード = A.部署コード) AS "部署名" , (select 名称 from MASTER_CODE where 区分=1000 AND レベル=3 AND コード = A.課コード) AS "課名" , (select 名称 from MASTER_CODE where 区分=1100 AND レベル=1 AND コード = A.得意先コード) AS "得意先名" , (select 名称 from MASTER_CODE where 区分=1100 AND レベル=2 AND コード = A.得意先住所コード) AS "得意先住所" from TRAN_TABLE A ;

6mmruled
質問者

お礼

早急な回答ありがとうございました。 本日、試してみました。 かなりのレスポンス改善があり、驚きました。 質問内容では、1組の例を記載していましたが 実際は上のようなVIEWをさらに5個結合させていましたので 15倍から30倍の速さのレスポンスになりました。 SQL文もシンプルになり助かりました。 ありがとうございました。

関連するQ&A

  • SQL文の実行速度について

    こんにちは。SQLを勉強しています。 質問をさせてください。 Oracleテーブル(test_table:レコード数はかなりあると考えて構いません) にnumber(int),value(varchar), code(varchar)の3つのフィールドが存在 するとします。 今、codeを指定してvalueを取得したいと考えています。 (1)---------------------------- select value from test_table where code='001'; select value from test_table where code='002'; select value from test_table where code='003'; (2)---------------------------- select code, value from test_table where code='001' or code='002' or code='003' (1)と(2)ではどちらが実行速度が速いのでしょうか? 実際に実行すればわかることですが、そういった環境が ないので、確認できません。宜しくお願い致します。

  • 日付の最大値を検索条件にする方法

    お世話になります。 ORACLEのMAX()関数を使用して、 下記内容を取得するSQLを作成しています。 ・商品テーブルから商品コードを取得したい ・上記の取得条件として、商品テーブルの日付項目が最新日付のレコードのみを 取得したい ・上記の取得条件に加えて、指定したいくつかの商品に該当するもののみを 検索対象としたい 【SQLサンプル】 SELECT 商品コード FROM 商品テーブル WHERE 商品コード IN (101, 102, 103) AND 在庫区分 = '0' AND 日付 = (SELECT MAX(日付) FROM 商品テーブル WHERE 商品コード IN (101, 102, 103) AND 在庫区分 = '0' ) AND ランク = (SELECT MAX(ランク) FROM 商品テーブル WHERE 商品コード IN (101, 102, 103) AND 在庫区分 = '0' ) 上記以外の書き方で何か良い書き方があれば、 ご教授願えますか? よろしくお願いいたします。

  • 結合が上手くいきません

    以下のテーブルがあるとします table1 名前|住所コード|勤務地コード table2 コード|名称 テーブル1の検索結果にテーブル2の名称を引っ張ってきて取得したいのですがどうやるのでしょうか? SELECT * from table1 INNER JOIN table1.住所コード ON table2.コード INNER JOIN table1.勤務地コード ON table2.コード これではうまくいきませんでした。 SELECT (select 名称 from table2 where table2.コード=table1.住所コード),(select 名称 from table2 where table2.コード=table1.勤務地コード) FROM table1 これは上手くいくのですが重いらしいので、、、

    • ベストアンサー
    • MySQL
  • SELECTのスピード

    SELECTのスピードでどの方法が 検索スピードが速いのか教えてもらいたいのですが Aのテーブル DENNO CODE Bのテーブル CODE NAME Aのテーブルを主にAのCODEでBのテーブルを参照したい時 (1) SELECT A.DENNO,A.CODE, (SELECT B.NAME from B where A.CODE=B.CODE) AS NAME from A (2) SELECT A.DENNO,A.CODE,B.NAME FROM A LEFT JOIN B ON A.CODE=B.CODE (3) SELECT A.DENNO,A.CODE,B.NAME FROM A , B WHERE A.CODE=B.CODE(+)

  • PostgreSQLでの外部結合

    PostgreSQLでの開発をしております。 今まで、Oracle,SQLServerでしか開発経験がなく、外部結合のやりかたがピンときません。 Oracleでいう以下のSQLをPostgreで書く場合、どのように記載すればよいのでしょうか? SELECT m.no, c.value FROM main_table m, code_master c WHERE m.code = c.code(+) AND m.update_date > sysdate AND c.content_flg = "0"; main_tableのcodeがNullや、code_master.codeに対応する値がない場合でも、レコードを持ってくる。 ※Oracleなどは独自のやりかたを行っているので、Joinを使うやりかたのほうがSQLとしては正しいのですが・・・。

  • SQL文をどう記述すれば良いか教えて下さい。

    テーブルAが以下の様に在るとします。 連番(ユニークキー)/日付/社員コード/所属コード そして、社員コード、所属コードの名称が、テーブルBに登録されています。 区分/コード/名称 ここで、区分+コードでユニークキーとなっていて、区分=1は社員コード、区分=2は所属コードとなっています。 単純に、テーブルAから、ある日付を指定して、連番・社員コード・所属コードを取得する場合、SQL文は以下の様になると思います。 SELECT 連番,社員コード,所属コード FROM テーブルA WHERE 日付='20030401' この時、同時に、テーブルBから社員コードに対応する名称、及び所属コードに対応する名称を取得したい場合は、どの様に記述すれば良いのでしょうか?

  • サブクエリーでデータが存在しないレコードを取得したいです

    サブクエリーで指定したb_masterにレコードが存在せず、a_masterにレコードがある人のデータを取得したいのですが、以下のSQLを変更して実現可能でしょうか? SELECT * FROM user_master as u WHERE code='6' AND (u.code,u.username) = (SELECT code, username FROM b_master as b WHERE b.no = '38' AND b.status >= 1 AND b.code = u.code AND b.username = u.username ) よろしくお願いいたします。

  • SELECT実行結果のレスポンス改善について

    いつもお世話になっております。 Oracle9i+XP(CPU=PentiumCore2Duo,メモリ=2MB)の環境にて、以下のようなSELECT文なのですが、実行結果が出るまでに約45分もかかってしまいます。 何が悪いのか切り分けるために、以下の副問い合わせのみを切り取ってSQLPLUSで実行してみると15件ずつが約10秒おきに返ってくるという現象が確認できたため、おそらくこの副問い合わせではないかと思っております。 データ件数としては、ZAIテーブルが約6万件、MEISAIテーブルが約12万件、VIEW_ROOM_CALENDERビューが約6千件で、それ以外はしれとります。 一応すべてのテーブルのキーにはインデックスがはられているようです。 色々と調べてautotraceにて実行計画などを見てみましたが正直よくわかりませんでした。 テーブル構造やリレーション、カラム数、レコード長など情報が少なく大変申し訳ないのですが必要であれば提示させていただきますので、SQL文がおかしいとか、ネック部分の調べ方とか、なにかヒントのようなものでも結構ですので、どなたかご教授いただけませんでしょうか? 宜しくお願い致します。 select D.KANJYA_NO || ',' || D.NAME || ',' || A.BYOU_NAME || ',' || count(COL_PT) || ',' || count(COL_OT) || ',' || count(COL_ST) from ( -- 副問い合わせ select B.KANJYA_NO as KAN_NO, B.KAIKEI_DATE, G.BYOUTOU_NAME as BYOU_NAME, (case when C.MASTER_CODE in ('01017' , '01022' , '01025') then B.TOTAL_KAISUU else NULL end) as COL_PT, (case when C.MASTER_CODE in ('01019' , '01021' , '01023') then B.TOTAL_KAISUU else NULL end) as COL_OT, (case when C.MASTER_CODE in ('01016' , '01020' , '01024') then B.TOTAL_KAISUU else NULL end) as COL_ST from ZAI&1 B inner join MEISAI&1 C on C.NYUUGAI = B.NYUUGAI and C.KANJYA_NO = B.KANJYA_NO and C.ZAI_NO = B.ZAI_NO and C.KAIKEI_DATE = B.KAIKEI_DATE and B.KAIKEI_DATE Like '&1' || '%' and B.NYUUGAI = 2 and B.KANJYA_NO not like '*%' and C.MASTER_CODE in ('01017','01022','01025','01019','01021','01023','01016','01020','01024') inner join NYUUIN_ROOM E on C.KANJYA_NO = E.KANJYA_NO inner join VIEW_ROOM_CALENDER H on E.KANJYA_NO = H.KANJYA_NO and C.KAIKEI_DATE = H.YYYYMMDD and lpad(E.ROOM_NO,'10','0') = TO_NUMBER(H.ROOM_NO) inner join ROOM_TABLE F on E.ROOM_CODE = F.ROOM_CODE inner join BYT_TABLE G on G.BYOUTOU_CODE = F.BYOUTOU_CODE ) A inner join KANJYA D on A.KAN_NO = D.KANJYA_NO group by D.KANJYA_NO, D.NAME, D.BIRTH, A.BYOUTOU_NAME ;

  • ビューで引数を使いたい

    4つのテーブルのいずれかをアクセスしますが、 select文はひとつでwhereでテーブルを指定したいので、  例:select * from ビュー where table_no=1 とかで、table_noの値でアクセスするビューは 作れますか? ※この例の場合、select * from table1が実行したい。 4つのテーブルは全て同じ構造で、 データが違うのみです。

  • こういうSELECTは可能でしょうか?

    テーブルA ---------- コード 区分 金額1 金額2 というテーブルがあるとして、その中から、 区分=1 AND 金額1>=0 の時は金額1、 区分=1 AND 金額1< 0 の時は金額2、 区分=2 AND 金額2>=0 の時は金額2、 区分=2 AND 金額2< 0 の時は金額1 をSELECTしたいのですが、1つのSELECT文で抽出する事は可能でしょうか? SELECT ・・・ ←ここにどう書けば良いんでしょうか? FROM テーブルA;