2つのテーブルを(内部)結合させる場合、
INNER JOINによる結合と
WHERE句に結合条件を記述する2通りの方法が
あると思いますが、どちらが早いのでしょうか?

なお、Oracle9i、ルールベースにて構築されています。
テーブルの内容、SQL文は下記のとおりです。

ご教授よろしくお願いします。

■表 A
項目A-1 ・・・PRIMARY KEY1、INDEX1
項目A-2 ・・・PRIMARY KEY2、INDEX2
項目A-3 ・・・PRIMARY KEY3
項目A-4

■表 B
項目B-1 ・・・PRIMARY KEY1、INDEX1
項目B-2 ・・・PRIMARY KEY2、INDEX2
項目B-3 ・・・PRIMARY KEY3
項目B-4

※項目A-1と項目B-1にて結合。
 項目A-2が"01"と等しいレコード。

表Aのレコード件数>表Bのレコード件数


【WHERE句にて結合】
SELECT * FROM A,B
where A.項目1 = B.項目1
and A.項目2 = '01'

【INNER JOINにて結合】
SELECT * FROM A
INNER JOIN A
ON A.項目1 = B.項目1
AND A.項目2 = '01'

このQ&Aに関連する最新のQ&A

A 回答 (3件)

表定義の見方がよくわかりませんが、PRIMARY KEYを3つのカラムに設定している時点でインデックスは死んでしまっているような気がするのですが。



結合方法をWHERE句に記述してもINNER JOINを使用しても実行計画が変わることはないようです。

ただし、LEFT JOIN, RIGHT JOINを使用した場合は強制的にコストベースになるので注意が必要です。

また、FROM句でA, Bの順に記述されていますが、A.項目2 = '01'の条件で絞り込んでも、まだ

Aの件数 > Bの件数が成り立つのでしょうか?

もし、これで逆転するようなら、A.項目2にインデックスを作成し、FROM句をB, Aとした方が性能がよくなるように思われます。

ちなみに、ご存知かも知れませんが、ルールベースがサポートされているのは9iまでで、10gからは完全に廃止されています。
    • good
    • 0
この回答へのお礼

お礼が遅くなって申し訳ありません。
ご指摘ありがとうございました。

お礼日時:2005/04/25 10:56

オプティマイザは、マイナーバージョンでも変更されると聞きますし、


COMPATIBLE 初期パラメータでも、変動します。
どちらが高速かは、わかりませんが。
(+)演算子の未来も暗そうなので、WHEREで結合条件を書くのは控えて
INNER JOIN で書いていった方が将来明るいと思います。

どうしても調べたいならば、TRACEすれば個別のケースでは優劣は付くかもしれませんが
それで、100%の正解にはならないと思います。

あと、#2さんの指摘に加えて、
どのようなパターンだとしても(複合でも単独でも)、インデックスが冗長のように見えます。
    • good
    • 0
この回答へのお礼

お礼が遅くなって申し訳ありません。
ご指摘ありがとうございました。

お礼日時:2005/04/25 10:54

説明に出てくる”PRIMARY KEY1”、”PRIMARY KEY2”の意味がわかりません。


複数項目で設定したプライマリキーの第一項目、第二項目の意味でしょうか?
INDEX1,INDEX2も不明ですが..

【WHERE句にて結合】と【INNER JOINにて結合】の違いは、
従来型の記述か、ANSI構文かの違いなので、
それによる速度差は無いのではないかと思いますが、
実行計画を見ないと確かなことは言えません。
    • good
    • 0
この回答へのお礼

お礼が遅くなって申し訳ありません。
ご指摘ありがとうございました。

お礼日時:2005/04/25 10:54

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q外部結合と等価結合のパフォーマンスの違いについて(ビューの場合)

Oracle10gでのSQL文の違いについて教えて下さい。

前回の質問は、ストアドプロシージャに記述
されていて、バッチとして動かしています。
と書きましたが、ビューの場合のパフォーマンスの違いは
どうなるのでしょうか?ビューの場合も同じような現象です。
下記の2つのSQL文は外部結合ありと外部結合なしの違いだけで、
他は変わりありません。
外部結合ありのほうは
結果がすぐに返されるのですが、外部結合なしのほうは
結果が返ってこない、あるいはかなり時間がかかるという
現象が起きています。
SQL文は簡略して記述していますが、SELECT句には、
TO_CHAR()やSUM(CASE WHEN ...THEN ...ELSE...)が使用してあり
少し重くなる処理も含まれています。
この2つのSQL文でパフォーマンスに影響している原因は
何なんでしょうか?オプティマイザとか実行計画とかの
説明を読んだのですが、いまいちよく解りません。。
自分では中級者以下だと思っていますので、わかりやすく
説明して頂けたら助かります。宜しくお願い致します。

(外部結合ありのSQL)
SELECT
 a.項目1,
 a.項目2,
 a.項目3,
 a.項目4,
 a.項目5
FROM
 TBL_A a,
 TBL_B b
WHERE
 a.項目1 = b.項目1(+) AND
 a.項目2 = b.項目2(+) AND
 a.項目3 = b.項目3(+) AND
 a.項目4 = b.項目4(+) AND
GROUP BY
 a.項目1,
 a.項目2,
 a.項目3,
 a.項目4,
 a.項目5

(外部結合なしのSQL)
SELECT
 a.項目1,
 a.項目2,
 a.項目3,
 a.項目4,
 a.項目5
FROM
 TBL_A a,
 TBL_B b
WHERE
 a.項目1 = b.項目1 AND
 a.項目2 = b.項目2 AND
 a.項目3 = b.項目3 AND
 a.項目4 = b.項目4 AND
GROUP BY
 a.項目1,
 a.項目2,
 a.項目3,
 a.項目4,
 a.項目5

Oracle10gでのSQL文の違いについて教えて下さい。

前回の質問は、ストアドプロシージャに記述
されていて、バッチとして動かしています。
と書きましたが、ビューの場合のパフォーマンスの違いは
どうなるのでしょうか?ビューの場合も同じような現象です。
下記の2つのSQL文は外部結合ありと外部結合なしの違いだけで、
他は変わりありません。
外部結合ありのほうは
結果がすぐに返されるのですが、外部結合なしのほうは
結果が返ってこない、あるいはかなり時間がかかるという
現象が起きています...続きを読む

Aベストアンサー

オラクルのオプティマイザは、テーブルの検索の方法を決めますが、外部結合と内部結合で
立案される実行計画に違いがあり、内部結合の方が合理的な検索方法を立案しているので
結果的に、内部結合の方が速いという話なんですが・・

実行計画を見なければ、判りませんが、
・外部結合はbに対して全表検索を選択した。
・内部結合では、bを索引検索を選択した。
・bの検索量が、bの格納件数のうち、ごく一部なので、全表検索と索引検索では、極端に検索時間が違う。
ということなんだと思います。(推測なので、実は違うかも知れません)

オラクルのマニュアルで、パフォーマンスチューニングガイドというマニュアルがあると思うので、
一読されることをお勧めします。


ちなみに、お書きになったSQLは何か変です。
内部結合のSQLは、bの項目を返さないので、実質的にbに存在するかのチェックを行っているに等しいものです。
書き方や流儀の問題で、内部結合が良いのか、exists条件が良いのか、in条件(メンバーシップ検査)が良いのか
変わってくると思いますが、一応理解できるものです。
しかし、外部結合のSQLについては、bを検索するけど、何もしない??理解に苦しむSQLになっています。
基本的に、内部結合より遅くなる外部結合を、わざわざ書いてみた、というように感じます。
(一般論ですが、同じ書き方をしたら、外部結合は内部結合と同等以下です)

オラクルのオプティマイザは、テーブルの検索の方法を決めますが、外部結合と内部結合で
立案される実行計画に違いがあり、内部結合の方が合理的な検索方法を立案しているので
結果的に、内部結合の方が速いという話なんですが・・

実行計画を見なければ、判りませんが、
・外部結合はbに対して全表検索を選択した。
・内部結合では、bを索引検索を選択した。
・bの検索量が、bの格納件数のうち、ごく一部なので、全表検索と索引検索では、極端に検索時間が違う。
ということなんだと思います。(推...続きを読む

Q外部結合のパフォーマンスチューニングできますか

下のSQL文がパフォーマンスが非常に悪いです。
何かチューニングする方法ありませんか。

Oracle8.1.7 
OSはWin2000serverSP2

◇SQL文
SELECT A.HINCD , B.TANCD ,A.SIZE,A.COLOR
FROM TB_TBLA A ,TB_TBLB B
WHERE A.KA_CD = B.KA_CD(+)"
AND A.HINCD = B.HINCD(+)
AND A.JIGYOCD = 1
AND A.BRCD = 20
AND A.BUCD = 300

TB_TBLAの主キーは、JIGYOCD、BRCD、BUCDです。
TB_TBLBの主キーは、KA_CDです。

また、TB_TBLAの件数は、約10万件、TB_TBLBは3万件だとしたら、
読み込み件数は10万*3万件となるのでしょうか。

よろしくお願いします。

Aベストアンサー

>"iniSID.ora”の中の”SORT_AREA_SIZE”を変更するような感じで色々書いてあるのですが、iniファイルには”SORT_AREA_SIZE”たる記述がありません。
初期化パラメータファイル(init.ora)にありませんか。
ただ初期化パラメータの「sort_area_size」を大きめに変更する場合、同時に「sort_area_retained_size」も変更しないと意味がないかと思います。

それと、init.oraを変更して、Oracleを再起動する野は大変ですよね。
ALTER SESSION SET SORT_AREA_SIZE=値;で設定していろいろ試してから変更するほうがらくだと思います。

QSELECTで1件のみ取得するには?

こんにちわ。
いまORACLE9iを使用している者です。

ACCESSでは
SELECT TOP 1 項目名 FROM テーブル名
ORDER BY 項目名;
で並べ替えたデータ群のうち,先頭の1件だけを
取ることができますが,
ORACLEでそのような機能(SQL)はあるでしょうか?
教えてください。
よろしくお願いします。

Aベストアンサー

order by と rownum を併用する場合は注意が必要です。

[tbl01]
cola | colb
------------
1000 | aaaa
1001 | bbbb

というデータがある場合、
select cola from tbl01 where rownum < 1 order by cola desc;
とすると、「1001」ではなく、「1000」が返されます。
これは、order by の前に rownum < 1 が適用されてしまうからです。

解決するには、
select aaa from (select cola aaa from tbl01 order by cola desc) where rownum = 1;
とすれば良いです。

Q3つの表の外部結合

表A、B、Cの3つがあり、Aのすべての行を出力したいと考えています。
外部結合を用いるのだとは思うのですが、3つの表に対して行う場合の
書き方がわからず困っています。
ご教授いただけないでしょうか?
select * from a,b,c
where a.商品ID =b.商品ID (+) and b.商品ID (+) =c.商品ID (+)
としてみましたが、うまくいきませんでした。

Aベストアンサー

ansi構文の趣旨からいえば、結合条件と絞り込み条件は分けて書くので・・

select *
from a
left join b on (a.商品ID =b.商品ID)
left join c on (b.商品ID =c.商品ID)
where a.年月 = 任意の値

と書くのが一般的でしょうね。

QSQLで特定の項目の重複のみを排除した全項目を取得する方法

私は仕事上でデータベースを扱っていて、タイトルのような処理を行う必要があるのですが、いかんせん方法がわからずネット上を検索しても同様だったためここで質問させていただきます。

質問点を簡単に説明いたしますと、
たとえばAというテーブルがあって、

項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 A    い    ア    以
 A    う    ア    宇
 B    え    イ    江
 B    お    イ    尾

上のような構造になっている場合に「項目名1」について重複している項目を排除し、結果として


項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 B    え    イ    江

上のようなデータを取得したいのです。
この時に、Aの重複を排除して取得するレコードは1~3行目のどれでもよいです。
また、データを取得する際には必ずそのレコードの「全項目」を取得したいのでDistinctはうまく使えませんでした。

どなたか詳しい方、方法を教えてくださると幸いです。回答お待ちしております。

私は仕事上でデータベースを扱っていて、タイトルのような処理を行う必要があるのですが、いかんせん方法がわからずネット上を検索しても同様だったためここで質問させていただきます。

質問点を簡単に説明いたしますと、
たとえばAというテーブルがあって、

項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 A    い    ア    以
 A    う    ア    宇
 B    え    イ    江
 B    お    イ    尾

上のよ...続きを読む

Aベストアンサー

比較可能で一意性のある値をもてる項目6をテーブルに追加して、

select T.* from T, (select Item1,min(Item6) as Item6 from T group by item1) W where T.item6=W.item6;

――ってやるのが、一番手っ取り早いと思います。
他のところに影響がでないのであればですが。
oracleならrowidを使うとか、レコードの更新時刻を突っ込むとか。

QInner join と Left joinの明確な違いは?

Inner join と Left joinの違いがよくわかりません。
教えてください。

Aベストアンサー

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
4               NULL
5               NULL
6               NULL
の6レコードが出力されますが、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 INNER JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3               3
の3レコードしか出力されません。

出てくる結果が違います。

テーブル1のフィールド1に、






が、

テーブル2のフィールド1に、






が入力されている場合、

SELECT [テーブル1].[フィールド1], [テーブル2].[フィールド1]
FROM テーブル1 LEFT JOIN テーブル2 ON [テーブル1].[フィールド1]=[テーブル2].[フィールド1];
では、結果は、
テーブル1.フィールド1 テーブル2.フィールド1
1               1
2               2
3           ...続きを読む

Qupdate文で改行を入れる

こんにちは。
いつもお世話になっています。

update文を使用して、データに改行を入れたいのですが、どうすればよいでしょうか。

対象列のデータ型はVARCHAR2です。

例えばSQLPLUSから、
SPL>update 「テーブル名」set 「対象列」='あ改行い改行う改行'
を投入し、そのあと
select 「対象列」 from 「テーブル名」
とすると
SQL>あ
SQL>い
SQL>う
と出てくればよいんですが、
SQL>update 「テーブル名」set 「対象列」='あ\nい\nう\n'
としても
SQL>あ\nい\nう\n
と、「\n」が文字列としてでてきてしまいます。

SPL>update 「テーブル名」set 「対象列」='あ
2い
3う'
と投入すると、期待通りになるのですが、
そうではなく一行にまとめたいのですがどうすれば良いでしょうか。

Oracle9iを使用しています。
宜しくお願いいたします。

Aベストアンサー

こんにちわyukio200263さん
以下のSQL文でどうでしょうか?

UPDATE 「テーブル名」
SET 「対象列」= 'あ' || CHR(13) || CHR(10) ||'い'

ちょっと長くなってしまいますが、一行で可能です。

Q実行計画の「COST」と「BYTE」について教えていただきたいです。

実行計画の「COST」と「BYTE」について教えていただきたいです。

書籍には
COST・・・・CBOによって見積もられた操作コスト。
BYTE・・・・アクセスされるバイト数のCBOのアプローチによる見積もり。
と書かれていますが、いまいちピンときません。


私は、
COSTは、検索するテーブルのデータ量が多いほうがコスト値が大きくなる。
BYTEは、検索条件に合致して取得できるデータが多いほうがバイト値が大きくなる。
と思っているのですが、正しいでしょうか?

Aベストアンサー

このあたりを参考にしてください。
COSTはデータ量だけではなく、その表やViewのアクセスに要する時間やSortや結合が必要なら、そのために必要なCPU時間等も考慮されています。
表があるHDDのアクセス速度なんかも考慮されているし、表のエクステントが複数になっているかとかも考慮されています。
書籍はわかりにくいかもしれませんが、嘘は少ないと思います。著者が思い違いをしてないとは言い切れませんが。

参考URL:http://otn.oracle.co.jp/forum/message.jspa?messageID=35016743

QWHERE句で結合。INNER JOINとの違い

MySQLで複数テーブルからデータ取得する際、
FROMの後に、テーブル名を2つ書いて、「WHERE」で繋げる書き方と、
「JOIN ★★ ON」で繋げる書き方では、何が違うのでしょうか?

・「INNER JOIN」と同じ意味でしょうか?
・書き方によっては、「LEFT OUTER JOIN」みたいにも書けるのでしょうか?

・普通は、どちらの書き方で書くとか、そういうお作法的な暗黙の了解はあるでしょうか?
・例えば「WHERE」だと3つ以上繋げられない(?)から、奨励されていない、とか…

Aベストアンサー

select *
from 表A, 表B
where 表A.列1 = 表B.列2 and 表A.列3 = 値



select *
from 表A inner join 表B on 表A.列1 = 表B.列2
where 表A.列3 = 値

は同じ結果となります。前者の方が古くからある構文,後者が新しい構文になります。新しいといっても20年は経っていますけれど。


> 普通は、どちらの書き方で書くとか、
> そういうお作法的な暗黙の了解はあるでしょうか?

旧構文は,結合を指定する要素がfrom句とwhere句に分かれてしまっているのに対して,
新構文では次のように各句の機能が明確ですから,join句の使用をお薦めします。

射影…select *
結合…from 表A inner join 表B on 表A.列1 = 表B.列2
選択…where 表A.列3 = 値


> 書き方によっては「LEFT OUTER JOIN」みたいにも書けるのでしょうか?

旧構文で外部結合を記述することもできますが,各データベース製品の独自構文になります。標準SQLの規格ではありません。


> 「WHERE」だと3つ以上繋げられない(?)から、奨励されていない、とか

そういう制限はありません。

select *
from 表A, 表B
where 表A.列1 = 表B.列2 and 表A.列3 = 値



select *
from 表A inner join 表B on 表A.列1 = 表B.列2
where 表A.列3 = 値

は同じ結果となります。前者の方が古くからある構文,後者が新しい構文になります。新しいといっても20年は経っていますけれど。


> 普通は、どちらの書き方で書くとか、
> そういうお作法的な暗黙の了解はあるでしょうか?

旧構文は,結合を指定する要素がfrom句とwhere句に分かれてしまっているのに対して,
新構文では次のように各句の機能が明確です...続きを読む

QViewにインデックスは張れますか?

件名の通りなのですが、作成したViewが遅くて困っています。
改善方法としてはViewを作成しないで従来のSQLにインデックスを張って取得する方法にしようかなと考えています。
なにかいい方法はありますか?

Aベストアンサー

Viewの元テーブルに適切なIndexを貼る、ではいけないのですか?


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報