(オラクルで)パフォーマンスに違いはありますか
Select * from Table1 T1
Inner Join Table2 T2 On T1.ID = T2.ID
そして
Select * from Table1 T1, Table2 T2
Where T1.ID = T2.ID
?
inner join ... on同等の結合基準を配置することと比較することで異なる結果がどのように発生するかはわかりませんwhere。
join
(オラクルで)パフォーマンスに違いはありますか
Select * from Table1 T1
Inner Join Table2 T2 On T1.ID = T2.ID
そして
Select * from Table1 T1, Table2 T2
Where T1.ID = T2.ID
?
inner join ... on同等の結合基準を配置することと比較することで異なる結果がどのように発生するかはわかりませんwhere。
join
回答:
番号!同じ実行プランで、次の2つのテーブルを見てください。
CREATE TABLE table1 (
id INT,
name VARCHAR(20)
);
CREATE TABLE table2 (
id INT,
name VARCHAR(20)
);
内部結合を使用したクエリの実行プラン:
-- with inner join
EXPLAIN PLAN FOR
SELECT * FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.id;
SELECT *
FROM TABLE (DBMS_XPLAN.DISPLAY);
-- 0 select statement
-- 1 hash join (access("T1"."ID"="T2"."ID"))
-- 2 table access full table1
-- 3 table access full table2
そして、WHERE句を使用したクエリの実行プラン。
-- with where clause
EXPLAIN PLAN FOR
SELECT * FROM table1 t1, table2 t2
WHERE t1.id = t2.id;
SELECT *
FROM TABLE (DBMS_XPLAN.DISPLAY);
-- 0 select statement
-- 1 hash join (access("T1"."ID"="T2"."ID"))
-- 2 table access full table1
-- 3 table access full table2
クエリオプティマイザーが正しく機能している場合、これらのクエリに違いはありません。これらは、同じ望ましい結果を指定するための2つの方法にすぎません。
JOINテーブルを結合するための条件は、WHERE句の「どこかに」ではなく、すぐに定義されているため、sは読みやすいと思います。テーブルの相互関係(たとえば)を定義するのではなくWHERE、データセットを制限するための節(たとえばWHERE DATE > (SYSDATE - 1))を予約することを好みWHERE T1.ID = T2.IDます。問題の例のような小さなテーブルの場合はほとんど違いがありませんが、複数のテーブルと複数の条件を含む大きなクエリの場合は、クエリがはるかに理解しやすくなると思います。
それらはまったく同じでなければなりません。ただし、コーディングの実践として、私はむしろ結合を参照したいと思います。それは明らかにあなたの意図を明確にします、
JOINコードを使用すると、説明がわかりやすいのでコードが読みやすくなります。
速度に違いはなく(テストしたばかりです)、実行プランは同じです。
Oracleについては知りませんが、SQL Serverでは古い構文が廃止されており、最終的にはなくなる予定です。新しいクエリでその古い構文を使用する前に、Oracleがその構文をどう処理するかを確認しました。
結合基準を他の必要なwhere条件と混合するのではなく、新しい構文を使用します。新しい構文では、何が結合を作成し、他にどのような条件が適用されているかがより明確になっています。このような短いクエリではそれほど大きな問題ではありませんが、より複雑なクエリを作成すると、混乱がさらに大きくなります。人々は基本的なクエリについて学習するので、複雑なクエリでそれが必要になる前に、結合構文の使用を学ぶことを好む傾向があります。
また、Oracleについて具体的には知りませんが、SQL Server 2000でも古いスタイルの左結合のSQL Serverバージョンに欠陥があり、一貫性のない結果(左結合がクロス結合になることもある)が発生することを知っています。中古。うまくいけば、Oracleが同じ問題に悩まされることはありませんが、確かに、左と右の結合は、古い構文で適切に表現するのが非常に難しい場合があります。
さらに、ANSII標準の結合を使用する開発者は、結合とは何か、および結合の意味を理解する傾向があるというのは、私の経験です(もちろん、これはあくまで個人的な意見であり、経験は異なる場合があります)。データベースからのデータ。データベースをよく理解しているほとんどの人は、より複雑なクエリを書く傾向があり、古いスタイルよりもANSII標準を使用して保守する方がはるかに簡単に思えるので、私は信じています。
【おまけポイントに…】
JOIN構文を使用すると、結合がすべて1行に含まれているため、結合をより簡単にコメント化できます。これは、複雑なクエリをデバッグする場合に役立ちます。
他の誰もが言うように、機能的には同じですが、JOINは意図の表明をより明確にします。したがって、あり、それは、特定の場合には、現在のOracleのバージョン(私はそれがない場合は考えている)のいずれかで、クエリオプティマイザを助けることがオラクル(誰がどんな考えを持っていない)の将来のバージョンでは、クエリオプティマイザを助ける、またはそれが可能ならば助けますデータベースのサプライヤを変更します。
それらは論理的には同じですが、ANSI構文を採用した以前のバージョンのOracleでは、より複雑なケースでバグが発生することが多かったため、Oracle開発者からの抵抗に遭遇することがあります。
パフォーマンスは同じでなければなりませんが、外部結合に関しては明確さが向上するため、結合バージョンを使用することをお勧めします。
また、意図しないデカルト積は、結合バージョンを使用して回避できます。
3番目の効果は、より単純なWHERE条件でSQLを読みやすくすることです。
テーブルが第3正規形であるシナリオでは、テーブル間の結合は変更されません。つまり、顧客と支払いに常に参加する必要があります。
ただし、結合とフィルターは区別する必要があります。結合は関係についてであり、フィルターは全体を分割することについてです。
標準に言及している著者もいます(Jim Melton、Alan R. Simon(1993)。新しいSQLの理解:完全なガイド。MorganKaufmann、11〜12ページ。ISBN978-1-55860-245-8。)は、FROM句でカンマ区切りのテーブルよりもJOIN構文を採用するメリットについて書いています。
私はこの見解に完全に同意します。
SQLを記述して同じ結果を得るにはいくつかの方法がありますが、チームワークを行う人の多くにとって、ソースコードの読みやすさは重要な側面であり、テーブルを特定のフィルターからどのように関連付けるかを確実に分離することは、ソースを明確にするという意味で大きな飛躍でしたコード。
2つのクエリの同一性は明らかであるように見えますが、いくつかの奇妙なことが起こります。結合述語をJOINからOracle 10gのWHEREに移動すると、クエリの実行プランが異なるクエリに遭遇しました(WHEREプランの方が優れています)が、この問題を簡略化されたテーブルとデータで再現することはできません。それは私のデータと統計に依存すると思います。オプティマイザーは非常に複雑なモジュールであり、魔法のように動作する場合があります。
DBの内部に依存しているため、この質問に一般的に答えることはできません。しかし、答えは「違いなし」でなければならないことを知っておくべきです。
本番環境でのspのタイムアウトの1つを検査し、代わりにxmlフィードから構築されたテーブルの内部結合を「where」句に変更したとき、今日この難題に直面しました。平均execが2.2秒になる前...実行プランの主な違いは、キールックアップの消失です...両方の方法を使用してテストするまでメッセージはわかりません。
乾杯。
どちらも結合であり、同じことを行う場所です。
キーウィックが言ったように、実行計画は同じです。
JOINステートメントの方が読みやすいだけなので、ON条件を忘れずにデカルト積を取得できます。これらのエラーは、SELECT * FROM t1、t2 WHERE t1.id = t2.some_fieldタイプの複数の結合を使用する長いクエリで検出するのが非常に難しい場合があります。
結合条件を1つだけ忘れると、クエリを実行するのに非常に長い時間がかかり、非常に多くのレコードが返されます。一部の人々はDISTINCTを使用してクエリにパッチを当てていますが、実行するのにまだ非常に長いです。
それが正確に理由です。JOINステートメントを使用することは確かにベストプラクティスです。つまり、保守性と可読性が向上します。
さらに、よく覚えていますが、JOINはメモリ使用量に関して最適化されています。