110

私が働いたすべての会社で、人々がまだ ANSI-89 標準で SQL クエリを書いていることがわかりました。

select a.id, b.id, b.address_1
from person a, address b
where a.id = b.id

ANSI-92 標準ではなく:

select a.id, b.id, b.address_1
from person a
inner join address b
on a.id = b.id

このような非常に単純なクエリの場合、読みやすさに大きな違いはありませんが、大きなクエリの場合、結合条件をグループ化してテーブルを一覧表示すると、結合で問題が発生する可能性のある場所を簡単に確認できることがわかります。すべてのフィルタリングを WHERE 句に保持しましょう。言うまでもなく、外部結合は Oracle の (+) 構文よりもはるかに直感的です。

私は ANSI-92 を人々に広めようとしていますが、ANSI-89 よりも ANSI-92 を使用することで具体的なパフォーマンス上の利点はありますか? 自分で試してみますが、ここにある Oracle のセットアップでは、EXPLAIN PLAN を使用できません。人々がコードを最適化しようとするのは嫌ですよね?

4

16 に答える 16

79

Peter Gulutzan と Trudy Pelzer による「SQL Performance Tuning」によると、テストした 6 つまたは 8 つの RDBMS ブランドのうち、SQL-89 と SQL-92 スタイルの結合の最適化またはパフォーマンスに違いはありませんでした。ほとんどの RDBMS エンジンは、クエリを最適化または実行する前に構文を内部表現に変換すると想定できるため、人間が判読できる構文に違いはありません。

また、SQL-92 構文の伝道にも努めています。承認されてから 16 年が経ち、そろそろ人々がそれを使い始める時が来ました! (+)また、SQL データベースのすべてのブランドが現在それをサポートしているため、非標準のOracle 構文や*=Microsoft/Sybase 構文を使い続ける理由はありません。

なぜ SQL-89 の習慣の開発者コミュニティを壊すのが難しいのかというと、本や雑誌の記事、または別のコードベースであり、これらの人々は新しい構文を抽象的に学習しません. パターンマッチする人もいれば、丸暗記する人もいます。

ただし、以前よりも頻繁に SQL-92 構文を使用している人を徐々に見かけるようになりました。私は 1994 年以来、オンラインで SQL の質問に答えてきました。

于 2008-12-02T15:05:27.293 に答える
17

ANSI092 標準にはかなり凶悪な構文が含まれています。自然結合はその 1 つであり、USING 句は別のものです。私見、テーブルへの列の追加はコードを壊すべきではありませんが、NATURAL JOINは最もひどい方法で壊れます。中断する「最善の」方法は、コンパイル エラーによるものです。たとえば、どこかで SELECT * を実行すると、列を追加できます。コンパイルに失敗します。失敗する次善の方法は、実行時エラーです。ユーザーに表示される可能性があるため、さらに悪いことですが、それでも何かが壊れているという素晴らしい警告が表示されます。ANSI92 を使用し、NATURAL 結合を使用してクエリを記述した場合、コンパイル時も実行時も中断されず、クエリは突然間違った結果を生成し始めます。これらのタイプのバグは潜行性です。レポートがうまくいかず、財務開示が正しくない可能性があります。

NATURAL Join に慣れていない方向け。両方のテーブルに存在するすべての列名で 2 つのテーブルを結合します。4 列のキーがあり、それを入力するのにうんざりしている場合、これは本当にクールです。問題は、Table1 に DESCRIPTION という名前の既存の列があり、Table2 に新しい列を追加するときに発生します。名前はわかりませんが、うーん、DESCRIPTION のような無害なもので、VARCHAR2 で 2 つのテーブルを結合しています。 (1000) 自由形式のフィールド。

USING 句は、上記の問題に加えて、全体的なあいまいさにつながる可能性があります。別のSO 投稿で、誰かがこの ANSI-92 SQL を見せて、それを読む手助けを求めました。

SELECT c.* 
FROM companies AS c 
JOIN users AS u USING(companyid) 
JOIN jobs AS j USING(userid) 
JOIN useraccounts AS us USING(userid) 
WHERE j.jobid = 123

これは完全にあいまいです。Company テーブルと user テーブルの両方に UserID 列を配置しましたが、何の不満もありません。company の UserID 列が、その行を最後に変更した人の ID である場合はどうなるでしょうか?

私は真剣です、なぜそのような曖昧さが必要だったのか誰か説明できますか? なぜ標準にそのまま組み込まれているのですか?

コーディングを通じてそこにコピー/ペーストする開発者の大規模なベースがあるというビルの意見は正しいと思います。実際、ANSI-92 に関して言えば、私は一種の人間であることを認めます。私がこれまでに見たすべての例では、複数の結合が括弧でネストされていることが示されていました。正直なところ、それはせいぜいSQLでテーブルを選択することを困難にします. しかしその後、SQL92 の伝道者は、実際には結合順序が強制されると説明しました。JESUS ... 私が見たすべてのコピー貼り付け作業者は、現在、実際に結合順序を強制しています。これは、95% の確率でオプティマイザー、特にコピー/貼り付け作業者に任せたほうがよい仕事です。

彼が言ったとき、トマラクはそれを正しく理解しました、

新しい構文があるからといって、新しい構文に切り替えることはありません。

それは私に何かを与えなければならず、私は利点を見ていません。そして、プラス面がある場合、マイナス面は無視するには大きすぎるアホウドリです.

于 2008-12-02T17:03:33.090 に答える
14

いくつかの理由が思い浮かびます。

  • 人は習慣的にそれをする
  • 人々は怠け者で、タイピングが少ない「古いスタイル」の結合を好みます。
  • 初心者は、SQL-92 結合構文に頭を悩ませていることがよくあります。
  • 新しい構文があるからといって、新しい構文に切り替えることはありません。
  • 人々は、新しい (そう呼びたい場合) 構文が持つ利点を認識していません。主に、外部結合を実行する前にテーブルをフィルター処理できることです。

私としては、すべての結合を SQL-92 構文で行い、可能な場合はコードを変換します。これは、よりクリーンで読みやすく、強力な方法です。しかし、クエリ結果を変更せずに入力作業が増えるという点で、新しいスタイルを使用するように誰かを説得するのは困難です。

于 2008-12-02T15:17:18.577 に答える
11

上記の NATURAL JOIN と USING の投稿への応答として。

なぜこれらを使用する必要があると思いますか? これらは ANSI-89 では使用できず、ANSI-92 用に追加されたもので、ショートカットとしてしか見ることができません。

結合を偶然に任せることは決してなく、常にテーブル/エイリアスと ID を指定します。

私にとって唯一の方法は ANSI-92 です。これはより冗長であり、構文は ANSI-89 の支持者には好まれませんが、JOINS を FILTERING からきちんと分離します。

于 2009-10-29T13:48:40.217 に答える
5

まず、SQL Serverでは、外部結合構文(* =)が常に正しい結果をもたらすとは限りません。これを外部結合ではなく相互結合として解釈する場合があります。ですから、それを使うのをやめる正当な理由があります。また、その外部結合構文は非推奨の機能であり、SQL Server2008以降の次のバージョンのSQLServerには含まれません。内部結合は引き続き実行できますが、一体なぜ誰もが実行したいと思うのでしょうか。それらは不明確であり、維持するのがはるかに困難です。結合の一部が何であり、実際にはwhere句が何であるかを簡単に理解することはできません。

古い構文を使用すべきではないと私が信じる理由の1つは、結合と、結合が実行することと実行しないことを理解することが、SQLコードを作成するすべての人にとって重要なステップであるためです。結合を完全に理解せずにSQLコードを記述しないでください。それらをよく理解していれば、ANSI-92構文がより明確で保守しやすいという結論に達するでしょう。古い構文よりもANSI-92構文を使用しなかったSQLの専門家に会ったことはありません。

私が会った、または古いコードを使用しているほとんどの人は、結合を本当に理解していないため、データベースにクエリを実行するときに問題が発生します。これは私の個人的な経験なので、常に真実であるとは限りません。しかし、データスペシャリストとして、私は何年にもわたってこのジャンクを信じられないほど修正しなければなりませんでした。

于 2008-12-02T23:14:10.893 に答える
4

私は学校でANSI-89を教えられ、数年間業界で働いていました。それから私はDBMSの素晴らしい世界を8年間離れました。しかし、それから私は戻ってきて、この新しいANSI92のものが教えられていました。私はJoinOn構文を学びましたが、実際にSQLを教えており、新しいJOINON構文をお勧めします。

しかし、私が見ている欠点は、相関サブクエリがANSI92結合に照らして意味をなさないように見えることです。結合情報がWHEREに含まれていて、相関するサブクエリがWHEREで「結合」されている場合、すべてが正しく一貫しているように見えました。ANSI 92では、テーブル結合基準がWHEREになく、サブクエリ「join」が含まれているため、構文に一貫性がないようです。一方、この不整合を「修正」しようとすると、おそらくそれが悪化するだけです。

于 2012-10-01T11:36:53.023 に答える
3

SQL Server 6.5 用に最初に作成されたクエリがありましたが、これは SQL 92 結合構文をサポートしていませんでした。

select foo.baz
from foo
  left outer join bar
  on foo.a = bar.a

代わりに次のように書かれました

select foo.baz
from foo, bar
where foo.a *= bar.a

クエリはしばらく前から存在していましたが、関連データが蓄積されたため、クエリの実行が非常に遅くなり、完了までに約 90 秒かかりました。この問題が発生するまでに、SQL Server 7 にアップグレードしていました。

インデックスやその他のイースターエッグをいじった後、結合構文を SQL 92 に準拠するように変更しました。クエリ時間は 3 秒に短縮されました。

乗り換えるにはそれなりの理由があります。

ここから転載。

于 2012-03-16T14:03:08.597 に答える
3

確かな答えはわかりません..これは宗教戦争です(Mac-Pcやその他よりも程度は低いですが)

かなり最近まで、Oracle (およびおそらく他のベンダーも) は ANSI-92 標準を採用していなかったと推測されます (Oracle v9 かそのあたりにあったと思います)。まだこれらのバージョンを使用していた (または、これらのバージョンを使用している可能性のあるサーバー間でコードを移植できるようにするために、古い標準に固執する必要がありました...

新しい結合構文ははるかに読みやすく、古い構文は、よく文書化されたいくつかのシナリオで間違った (不正確な) 結果を生成するため、これは本当に残念です。

  • 具体的には、結合の「外側」側にあるテーブルの結合に関連しない列に条件付きフィルター述語がある場合の外部結合。
于 2008-12-02T15:19:08.077 に答える
2

慣性と実用性。

ANSI-92SQLはタッチタイピングのようなものです。理論的には、いつかすべてが良くなるかもしれませんが、今では4本の指でキーを見るとはるかに速く入力できます。前進するためには後退する必要がありますが、見返りがあるという保証はありません。

SQLを書くことは私の仕事の約10%です。ANSI-89SQLでは解決できない問題を解決するためにANSI-92SQLが必要な場合は、それを使用します。(実際、Accessで使用しています。)常に使用することで既存の問題をより早く解決できる場合は、時間をかけて吸収します。しかし、構文について考えることなく、ANSI-89SQLを作成することはできます。私は問題を解決するために報酬を得ています。SQL構文について考えることは、私の時間と雇用主のお金の無駄です。

いつの日か、若いGrasshopperは、SQL3(またはその他)を使用する必要があると嘆く若者に対して、ANSI-92SQL構文の使用を防御することになります。そして、あなたは理解するでしょう。:-)

于 2008-12-02T17:31:04.457 に答える
1

人々が ANSI-89 を使用する理由は、老若男女のプログラマー、研修生、新卒者との私の実際の経験から得られたものです。

  • 彼らは (本ではなく) 見た既存のコードから SQL を学び、コードから ANSI-89 を学びます。
  • ANSI-89 はタイピングが少ないため
  • 彼らはそれについて考えず、どちらか一方のスタイルを使用し、両方のどちらが新しいか古いと見なされるかさえ知りませんし、どちらも気にしません
  • コードは、コードを維持する次のプログラマーへのコミュニケーションでもあるという考えは存在しません。彼らは自分たちがコンピューターと話していると思っていて、コンピューターは気にしていません。
  • 「クリーンコーディング」の技術は不明
  • 特にプログラミング言語と SQL の知識が非常に乏しいため、他の場所で見つけたものをコピーして貼り付けます。
  • 個人の好み

私は個人的に ANSI-92 を好み、ANSI-89 構文で表示されるすべてのクエリを変更して、目前の SQL ステートメントをよりよく理解するためだけに変更することがあります。しかし、私が一緒に仕事をしている人々の大半は、多数のテーブルに対して結合を作成するスキルを持っていないことに気付きました。彼らはできる限り良いコーディングを行い、最初に SQL ステートメントに遭遇したときに記憶したものを使用します。

于 2016-06-10T10:36:47.783 に答える
1

すべての学校を代弁することはできませんが、私の大学でコースの SQL モジュールを行っていたとき、彼らは ANSI-92 ではなく ANSI-89 を教えていました - 古い VAX システムで! クエリ デザイナーを使用していくつかのクエリを作成し、次に SQL コードを掘り下げるまで、Access を掘り下げ始めるまで、ANSI-92 にさらされることはありませんでした。結合がどのように完了するか、または構文の意味がわからなかったことに気づき、理解できるように深く掘り下げ始めました。

多くの場合、利用可能なドキュメントが正確に直感的であるとは限らず、人々は自分が知っていることに固執する傾向があり、多くの場合、仕事を成し遂げるために必要以上に学ぼうとはしません。採用に時間がかかる理由は簡単にわかります。

もちろん、いじり回して理解するのが好きな技術伝道者もいますが、それは「新しい」原則を採用して残りを改宗させようとするタイプの傾向があります。

奇妙なことに、多くのプログラマーが学校を卒業して進歩を止めているように私には思えます。これが彼らが教えられたことであるから、これがその方法であると考えています。目隠しを外すまで、学校は基本を教え、残りを自分で学ぶのに十分な理解を与えることだけを目的としており、実際に知っておくべきことの表面をかろうじてかじっただけであることに気づきます。その道を歩み続けるのはあなたの仕事です。

もちろん、これは私の経験に基づいた私の意見です。

于 2008-12-02T17:01:24.127 に答える
1

両方の構文を理解するのに十分なSQLを知っている平均的な開発者の観点から答えることができますが、必要なたびにinsertの正確な構文をグーグルで調べています... :-P (私は一日中SQLをやっているわけではありません) 、時々いくつかの問題を修正するだけです。)

実際には、最初の形式の方が直感的で、2 つのテーブル間に明らかな階層はありません。最初のフォームを示すおそらく古い本でSQLを学んだという事実は、おそらく役に立たない... ;-)
そして、 GoogleのSQL選択検索で見つけた最初のリファレンス(ほとんどフランス語の回答を返します... ) 最初に古い形式を示します (次に、2 番目の形式を説明します)。

「なぜ」の質問にいくつかのヒントを与えるだけです... ^_^ このトピックに関する優れた最新の本(DBにとらわれない)を読む必要があります。誰か提案があれば...

于 2008-12-02T15:26:10.463 に答える
0

Oracle は ANSI-92 をまったくうまく実装していません。特に、Oracle Apps のデータ テーブルには列が非常に豊富に用意されているため、いくつかの問題がありました。結合の列数が約 1050 列を超える場合 (これはアプリでは非常に簡単です)、論理的な意味をまったく持たない次の誤ったエラーが発生します。

ORA-01445: cannot select ROWID from a join view without a key-preserved table.

古いスタイルの結合構文を使用するようにクエリを書き直すと、問題が解消されます。これは、ANSI-92 結合の実装に責任があると思われます。

この問題に遭遇するまで、私は ASNI-92 の確固たる支持者でした。なぜなら、古いスタイルの構文では簡単すぎる偶発的なクロス結合の可能性を減らす利点があるからです。

しかし、今ではそれを主張するのははるかに難しいと思います。彼らはオラクルの悪い実装を指摘し、「私たちのやり方でやります、ありがとう」と言います。

于 2008-12-02T16:03:42.977 に答える