Oracle9iR2のパフォーマンス向上のためにSQLを最適化する方法はありますか?

このQ&Aのポイント
  • Oracle9iR2のテーブルを結合するクエリーがパフォーマンスの問題を抱えています。分析関数や他の方法を使用して、パフォーマンスを向上させる方法を探しています。
  • Oracle9iR2のテーブル結合を行う際に、パフォーマンスの低下が問題となっています。パフォーマンスを向上させるために、分析関数や他の手法を試していますが、良い解決策が見つかりません。
  • Oracle9iR2のテーブル結合によるパフォーマンスの低下に悩んでいます。分析関数や他の方法を使用して、クエリーを最適化し、処理速度を向上させたいと考えています。
回答を見る
  • ベストアンサー

1SQLで書けないものでしょうか

初めて投稿します。 よろしくお願いします。 現状、下記の様な構成のテーブルがあります。 DB :oracle9iR2 テーブル名:test 名前 型 ------- ------------- key_data VARCHAR2(10) rireki DATE read_data VARCHAR2(10) プライマリキーは、key_dataとrirekiです。 この、データの中から、key_data毎に最新のrirekiの情報だけを 取得したいと考えています。 そこで、下記の様にクエリーを組んでいたのですが、 select key_data, rireki, read_data from test inner join ( select key_data, max(rireki) AS rireki from test group by key_data ) test2 on (test.key_data = test2.key_data and test.rireki = test2.rireki) 複数のテーブルが、上記の様なキー項目と履歴を持つ形で 構成されている為に、複数のテーブルを結合すると途端に パフォーマンスが落ちて困っています。 ひょっとしたら、oracleなら分析関数か何かで1SQLで書けないものか (それで、処理速度が向上出来れば)と云うことで、自分で調べて みましたが、良い方法が見つかりません。 同様のお悩みをもたれた方で、対処法がありましたら教えていただけると幸いです。 よろしくお願いいたします。

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

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

  • ベストアンサー
回答No.1

分析関数での実現例: select key_data,rireki,read_data from (select x.*,rank() over(partition by key_data order by rireki desc) R from test) where R=1; 分析関数を使わない実現例: select * from test where (key_data,rireki) in (select key_data,max(rireki) from test group by key_data); あなたのSQLも含めて、それぞれの実行計画を比較すると 面白いと思いますよ。

ponta3rd
質問者

補足

ありがとうございます。 SQL見て、rankが利用できる事がわかりました。 ただ、rankを使用しても、fromに書かないとwhereできないんですね。 ところで、勉強不足ですみませんが、fromに副問合わせするのと、 同じテーブルをjoinするのとどちらが一般的に早いんでしょうか? #その為の実行計画って指摘を受けそうですが、PLAN_TABLEもSYS権限も #無いため、比較が出来ないでいます。 実際に走らせた比較ですと、どれも大きく速度差が見られない様子でしたので。 すみません、ご教授頂ければ幸いです。

その他の回答 (2)

  • 7colors
  • ベストアンサー率25% (29/114)
回答No.3

このようなのではどうか? SELECT A.KEY_DATA, A.RIREKI, A.READ_DATA FROM TEST A WHERE A.RIREKI = ( SELECT MAX(B.RIREKI) FROM TEST B WHERE B.KEY_DATA = A.KEY_DATA);

回答No.2

実行計画無しで、処理効率を追求することは不可能です。 SYS権限でないと実行計画がとれない訳ではないですが・・ 実行計画をとれないということであれば、トライ&エラーを 繰り返すしかないかと思いますよ。 (少ないとも、”こうすれば”絶対速くなるという王道はありませんので。) >どちらが一般的に早いんでしょうか? オプティマイザの判断次第です。 オプティマイザがどのような判断をしたのかが、実行計画で確認できます。

関連するQ&A

  • 一度のSQL発行で結果を得るにはどのようなSQLにすれば良いでしょうか

    一度のSQL発行で結果を得るにはどのようなSQLにすれば良いでしょうか? データベースはOracleです。 二つの履歴テーブルがあり、それぞれ主キーは「連番」です。 連番が最も大きい値の社員番号と社員名を取得しようとしています。 (他にもカラムはありますが質問では省略しています。) 連番は別に管理テーブルがあり、そちらから採番しているので 二つのテーブルで連番が重複することはありません。 【RIREKI_TBL_A】 連番 NUMBER(10) 社員番号 VARCHAR(7) 社員名 NVARCHAR(20) 【RIREKI_TBL_B】 連番 NUMBER(10) 社員番号 VARCHAR(7) 社員名 NVARCHAR(20)

  • テーブル自体のバックアップ

    教えてください。 今オラクルのDBにTEST1テーブルが存在するとします。 ------TEST1--------------------- id varchar(5) Primary Key name varchar(20) old int -------------------------------- 今このテーブルとまったく同じデータを持ち、同じ構成のテーブルTEST2を 作成したいと考えています。 (1)create table TEST2( id varchar(5) primary key, name varchar(20), old int ); (2)insert into TEST2( id, name, old) values (select id, name, old from TEST1); としてTEST2テーブルを作成して、TEST1のデータを格納していますが、 他の方法はないでしょうか? たとえばこんなコマンドはありませんが、 COPY TEST1 TEST2 とか、 オラクルマネージャみたいなもので、 コピペして、名前をTEST2にする とかなんでもいいです。 TEST1のバックアップをとりたいのですが・・・・ すみません、わかりづらい説明で。 宜しくお願い致しますm(_ _)m

  • 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)ではどちらが実行速度が速いのでしょうか? 実際に実行すればわかることですが、そういった環境が ないので、確認できません。宜しくお願い致します。

  • SQLについて

    お世話になっております 以下の内容、お分かりになる方ご教授お願い致します Win2000 Access2000 TESTテーブル Key1  Key2  Key3 100  5     1 100  5     2 100  5     3      ←X 100  10     4      ←X2 110  10     2      ←X3 各項目は全て数値型です 上記データ内容のときにKey1が100以上でKey2が5以上で Key3が3以上のデータを取得したいと思っております 結果としてXからX3までのデータを抽出したいのですが どの様に行えばよろしいでしょか? SELECT * FROM TESTテーブル WHERE Key1 >= 100 AND Key2 >= 5 AND Key3 >= 3 の様に組むとKey1が110の項目は取得できなくなります Key3 >= 3の様に組んでるのでだとは思いますが 組み方がわかりません 宜しくお願いします

  • SQLについて質問です。

    今あるテーブル1のカラムA(number型)と 全く同じテーブルにあるカラムB(varchar型)を つなげて (number型) IS (varchar型) A IS B … のように真ん中に『IS』を挟んで データを全て出したいのですが、 SQLの書き方がよくわかりません。 自分では select A ||'(' || IS || ')'|| B from table1 のように書くのでは?と思っていますが、 全く上手くデータをこの形で出すことができません。 このデータを出すためには どういったSQLを書けばよろしいのでしょうか? よろしくお願いします。

  • SQL文作成のお願い

    前提として下記のようなテーブルがあります。 テーブル名:test フィールド: 1)id: varchar, not null 2)name: varchar 3)date: timestamp with time zone, not null このテーブルに下記のようなレコードがあります。 '00001', 'A', '2005-01-01 00:00:00' '00001', 'B', '2005-07-01 00:00:00' '00001', 'C', '2005-11-01 00:00:00' '00002', 'X', '2005-01-20 00:00:00' '00002', 'Y', '2005-07-20 00:00:00' '00002', 'Z', '2005-11-20 00:00:00' ■今やりたいこと このテーブルからidごとにdateフィールド値が最近のレコードを取得したい。 ■やってみたこと 下記SQLを発行しました。 >select id, max(date) from test group by id order by id 結果==> 00001 2005-11-01 00:00:00 00002 2005-11-20 00:00:00 実際はnameフィールドの値も取得したいのですが、group by句を使うとフィールド指定ができませんでした。 ■だめだったSQL select id, name, max(date) from test group by id order by id どのようにSQLを書けばよろしいでしょうか?

  • 難しいSQL

    別の掲示板に質問したのですが、難易度が高いのかしばらく回答が得られなかったのでこちらに質問してみます。(別の掲示板の方は質問を取り消しました。)ちょっと急いでいるのでどんなものでも構いません。SQLに詳しい方、ご教示お願い致します。環境は、MySQL5.1.33(MacOSX版)を使用しています。 以下のようなデータベースがあります。マスター系となるユーザテーブルと、それを参照するトランザクション系の買い物テーブルです。このデータベースから、「※連続して買い物をしたユーザをSELECTしたい」のですがそのようなことは可能でしょうか?可能であるとすると、どのようなSQLを書けばよろしいでしょうか? ※「連続して」とは、日付をまたがって、という意味です。 例)2009/06/12、2009/06/13 (1)ユーザテーブル mysql> desc user; userid, int(11), primary key username varchar(15) (2)買い物テーブル mysql> desc purchase; purchaseid, int(11), primary key userid int(11) purchaseid date 今、買い物テーブルに以下のようにデータがある場合 mysql> select * from purchase; 1, 3, 2004-01-02 6, 1, 2004-04-03 5, 2, 2008-04-05 4, 2, 2000-01-19 3, 5, 2004-01-01 2, 1, 2001-11-10 9, 5, 2003-12-31 8, 1, 2007-04-05 7, 3, 2004-01-03 mysql> select userid from ... とすると3, 5を抜き出すようにしたいです。(3は2004/01/02, 2004/01/03だから。5は2003/12/31, 2004/01/01だから。) このselect文の書き方を教えて頂きたいです。お手数をおかけしますがよろしくおねがいします。

  • ACCESSのVBAのSQLを教えてください。

    テーブル1とテーブル2があり、それをUNIONで結合して、リンクさせたOracleのテーブルキーと 結合し、Oracleのテーブルにないキーを検索したいのですが、うまく出来ません。 ACCESSのVBAで作りたいのですが・・どうかご教授願います。 構成  テーブル1   項目名  Key 顧客コード1   名前 テーブル2     項目名   Key 顧客コード1   Key 顧客コード2      名前 Oracleのテーブル  テーブルB     項目名  Key 管理コード  テーブル1の顧客コード1とテーブル2の顧客コード2をUNIONでまとめたものをA1としA1.顧客コードとします それとOracleのテーブルであるテーブルBの管理コードと結合して テーブルBにないA1の顧客コードを抽出するSQL文を作成したいと思います。 (管理コード,顧客コード1,顧客コード2は同じ属性、同じ桁数) SELECT A1.管理コード FROM ( SELECT T1.顧客コード1 as 顧客コード FROM テーブル1 T1 UNION SELECT T2.顧客コード2 as 顧客コード FROM テーブル2 T2 )A1, テーブルB WHERE A1.顧客コード = テーブルB.管理コード AND テーブルB.管理コード IS NULL; エラーにはなりませんが、実行結果は、管理コード 0件です。データ的には、テーブルB側にはテーブル1にはあるがテーブルB側にないデータはあります。

  • 【至急】SQLの結合について教えてください。

    select * from A where ab = '1' and cd = '2' select ef from B where ab = '1' and cd = '2' and ef = '3' 至急質問させてください。 上記SQLを結合したいです。(Oracleです) 取得したいデータはAのテーブルの全項目で、 取得条件として、Bのテーブルの項目ef = '3' だったらという条件を加えたいです。 キー項目は両テーブルとも同じ(ab, cd)です。 どのようなSQLがスマートでしょうか。。 無知で申し訳ございませんが、ご教授いただけますと幸いです。 よろしくお願いいたします。

  • SQL MIN句

    テーブルには複数の主キーがあり、そのうちの3つの主キーを元に 最も古い日付の情報を取得したいです。 同じデータが複数あるので、副問い合わせ(=)でエラーになると思ったのですが エラーにならずにすべてのデータが取得されてしまいます。 テーブル id name sex date1 1 'A' '男' 20120101 1 'A' '男' 20120101 2 'A' '女' 20120102 select * from table where date1 = (select min(date1) from table where id = 1 and name = 'A' and sex='男'); 下記のような情報を取得するには、SQLとして間違えておりますでしょうか。 ↓ id name sex date1 1 'A' '男' 20120101 1 'A' '男' 20120101 お分かりの方、ご教授頂けませんでしょうか。 以上、よろしくお願い致します。