• 締切済み

WHERE句の実行順序

SELECT文などで、  WHERE 条件1  AND  条件2 と記述した場合、実行順序は上から(条件1⇒条件2)になるのでしょうか?それとも逆なのでしょうか? 同じ職場の方は、上からだとおっしゃるのですが、実行してみると下からのような気がするのですが・・・。私の気のせいでしょうか?

  • Oracle
  • 回答数8
  • ありがとう数18

みんなの回答

  • jmh
  • ベストアンサー率23% (71/304)
回答No.8

例えば、select * from dual where return_negative_slow() > 0 and return_negative_fast() > 0 のような場合、and を右から左に短絡評価してるような気がします。

  • entree
  • ベストアンサー率55% (405/735)
回答No.7

Oracle ではおっしゃっているように下から上に向かって解析されます。ただ、それは構文解析のルールであって、実行計画は構文解析が終了した後に、別の方法によって行われます。従って、WHERE 句の記述順を変えたからといって実行計画が変わることはありません。 また、10gになって廃止されてしまいましたが、ルールベース・アプローチでは、FROM 句については、後ろから判定される傾向があります。ただし、これは等結合の場合のみで、外部結合があったりするとこの傾向は当てはまらなくなります。 また、ルールベース・アプローチでは、できるだけ索引を使うような実行計画を立てる傾向がありますが、このとき、使える索引が複数あったりすると、後から作成された索引を優先的に使うというようなルールもあります。 ただし、片方が主キー索引で片方が普通の索引であるような場合は、ルールに乗っ取って主キー索引が優先的に使われることに注意してください。

回答No.6

#4です。 念のため書いておきますが.. ルールベースだから、FROMに書いた表を、必ず下から上に向かって、検索するというのは 間違いです。 ルールベースとコストベースで、実行計画を立てるための、決定要素は異なりますが、 ルールベースであっても、上から下へ検索するようなプランは作ります。 例えば、ルールベースオプティマイザで、次のSQLは select * from emp,dept where empno between 1 and 9999 and loc='DALLAS' and emp.deptno=dept.deptno emp表->dept表の順番になります。(ルール上、empの索引検索と判断したから) ルールベースで、よく”下から上に”と言われるのは、ルール上決定しきれない場合に、 そのような適当な判断をするからです。(=判断に窮すると、下から上に・・) 例えば、 select * from emp,dept where emp.deptno=dept.deptno; だと、下から上になります。 なお、ルールベースの場合、複数の索引がある場合に、どれを選択するか迷ったときも 何とも言えない索引選択をしてくれます。(^^; (どうも、索引名の昇順になる傾向)

  • mf2-256hd
  • ベストアンサー率14% (17/116)
回答No.5

No.2です。ちょっと、手元に資料がないのであいまいな回答になりますが。 他の方もおっしゃっていますが、現在のバージョンではコストベースとなっており今後はルールベースは廃止される方向です。 で、バージョンなどによりますが、FROM句は下から実行されることが多いです。そのため、軸になるTABLE(データ量が少ないTABLE)を下に書くのが基本とされていたと記憶しています。 しかしながらNO.3の方のとおり実行計画をみるのが一番ではあります。また、現在は、SQLの規格が国際的なやつに完全準拠(SQL98とかなんとか)し、JOIN句の使用を推奨していますので、今後はFROM句の記述順などはあまり有効にはならないとおもいます。 補足ですが、ヒントを使えばなるたけヒントに従います。(つまり実行順序を制御できる)しかしながら、「なるたけ」であって、Oracle君がやっぱこっちのほうがいいや!(コストベース)と判断すればそれまでです。 Oracleの方向性としては、今後こういった「チューニング」ということを極力なくす方向です。したがって、こういった知識も・・・話がそれました。 そういうわけで、要は「実行計画をある程度みよう。でもコストベースなんでOracle君次第だよ。だから統計情報は採ろうね!」とうい考え方でいいんではないでしょうか。

回答No.4

WHEREでの条件判断の順番は、オラクルの都合で、順番が決まります。 記述した順番でも、その逆順でもありません。 一般的プログラム言語の場合、論理演算子と()での優先順位を考慮しつつ 書いた順番に評価していきますが、RDBの場合、WHEREに書かれた要素が 実行計画で、索引の使用する/しないに影響します。 そのため、評価の順番が状況次第で逐次変化します。 たとえば、 select * from emp where to_number(ename)=0 and empno=9999 and to_number(deptno)=0 としたとき、 ワザと数値変換できないフィールドを数値変換しているので、 上から評価しても、下から評価しても、エラーを返すべきですが、 真ん中の要素が、プライマリキーであるため、実行計画で、 索引検索すべしとされました。そのため、真ん中の要素を 一番最初に評価し、そのあと、他の条件を判断することに なります。今回の場合、索引検索で0件となるので、その他の条件を 判断せず、終了する。(=エラーにはならない)

  • rgm79kura
  • ベストアンサー率100% (1/1)
回答No.3

まず答えとして、条件の実行順序ですが必ずしも記述した順番ではありません。 条件が適用される順番=データを取得してくる順序になりますが、同じSQL文でもOracleの設定(ルールベースかコストベースか)、データの状態、インデックスの有無、等々によって左右されるため、一概にこういう順番になりますということはありません。 これは、Oracleのオプティマイザという機能がSQL文を解析した後に、できるだけ速く結果を返すようにさまざまな情報からデータを取得する順番を決めるからです。(これを実行計画と呼びます。) そのため、実際にどういう順番で取得してくるかはSQLの実行計画を確認してみないとわかりません。 >下から上だと思った根拠は、WHERE句に条件を2つ記述して、2つともにミスがあった場合、下の条件のミスに対してエラーメッセージが返ってきたためです。 とありますが、これはあくまで構文解析の順番になります。構文解析がOKになってから実行計画が作成され、実行計画を元にデータが取得されるので、エラーの発生順と実行順序は関係ないです。 実行計画について調べてみるとパフォーマンスを考慮したいいSQL文が書ける様になると思います。

  • mf2-256hd
  • ベストアンサー率14% (17/116)
回答No.2

下から上というのはFROM句と勘違いされていると思います。

floren
質問者

お礼

ご回答ありがとうございます。 やはりWHERE句は上から実行されるのですね。下からというのは私の思い違いだったんですね(^^; FROM句の順序についても全く知らないのですが、FROM句では下から実行されるものなのでしょうか? FROM句の実行というのが、いまひとつピンとこないのですが、 FROM (SELECT ○○ FROM ×× ・・・) AS TABLE1,    (SELECT △△ FROM □□ ・・・) AS TABLE2 のように、FROM句の中にSELECT文を記述した場合に、下のTABLE2の方から先に実行されるということなのでしょうか? FROM TABLE1,    TABLE2 のように、SELECT文を記述しない場合には、実行順序は関係あるのでしょうか?(例えば、WHERE句の実行順序に関わってくるとか・・・) ご教示いただければありがたいです。

  • kokorone
  • ベストアンサー率38% (417/1093)
回答No.1

上からというか、「左から右へ」が原則です。 下から上というのは、どういう根拠なのでしょうか?

floren
質問者

補足

ご回答ありがとうございます。 例えば、  WHERE 会員番号 = 1234  AND  性別 = '男' と打ったとすると、 先に会員番号で絞り込んで、さらに性別で絞り込むのか、 それとも性別で絞込んだ後、会員番号で絞り込むのか、ということが知りたいんです。 SQLの記述にミス(列名の間違いや、データ型の不一致など)があった場合、エラーメッセージが帰ってきますよね。 下から上だと思った根拠は、WHERE句に条件を2つ記述して、2つともにミスがあった場合、下の条件のミスに対してエラーメッセージが返ってきたためです。

関連するQ&A

  • WHERE句の条件の記述の順序

    PRIMARY KEYとINDEXがテーブルに設定されている場合、 検索条件に記述する順番はどのようになるのでしょうか? 下記のテーブルがあり、SELECT文をつくろうと 考えています。 テーブル:foo 項目  PRIMARY KEY  INDEX ----------------------------------- a 1 b 2 1 c 3 d 2 (1)PRIMARY KEYを優先してWHERE句の順番を決める↓ SELECT * FROM foo WHERE a = "AAA" AND b = "BBB" AND c = "CCC" AND d = "DDD" (2) それともINDEXが設定されている項目を先に記述する↓ SELECT * FROM foo WHERE b = "BBB" AND d = "DDD"   AND a = "AAA" AND c = "CCC" (1)と(2)ではどちらの性能がよいのでしょうか?

  • ORACLEでwhere句の検索順序

    Oracle9i windows2000です。 以下のようなテーブルがあります。 table_a ----------------------- id   NUMBER(10,0) NOT NULL, sort   NUMBER(10,0) NOT NULL, name   VARCHAR(10), text   VARCHAR(255) この条件で、以下のふたつのSELECT文を発行した時、パフォーマンスが良いのはどちらですか? Oracleでは後ろから検索されると聞いたことがあるのですが本当でしょうか? ※idにプライマリキー、 id,sortにインデックスが貼ってあります。 (1)SELECT text FROM table_a WHERE id = 1 AND sort = 2 AND name = 'a' (2)SELECT text FROM table_a WHERE name = 'a' AND sort = 2 AND id = 1

  • where句への指定

    where句に、次のような条件を指定したいのですが、どのようにすればよいでしょうか?教えてください。 SQL文を実行した日の03:00:00より新しいレコード SQL文は周期的に実行するので、実行した日は変わります。

  • SQLのWHERE句を条件によって追加したい

    SQLのWHERE句にパラメータで渡された値がnullでない場合は条件に 含めるようにしたいのですが、書き方が分かりません。 CASEを使って書いてもエラーになってしまいます。 SELECT 項目1 ,項目2 FROM テーブル WHERE 条件1 = パラメータ1 AND 条件2 = パラメータ2 -- パラメータ3がnullでない場合は下記条件を付けたい AND 条件3 = パラメータ3 使っているのはpostgresqlです。 よろしくお願いします。

  • WHERE句の条件を区別する

    こんばんは 業務で以下の切り分けをしたいのですが、可能でしょうか。 SOAP通信を使っていて、パフォーマンス的な観点から、select文は使用したくないと思っています。 ■環境 ・PHP5 ・MySQL ・FreeBSD6 ■やりたいこと Update文で更新を行ったときに、データそのものがなくて更新できなかったのか、データは存在するがPK以外の条件がマッチしなくて更新できなかったのかで、エラーコードを分けたい 例えば、  update tableA set column1='aaa' where pk1=1 and pk2=2 and column2='bbb'; といったSQL文で、「pk1=1 and pk2=2」に合致するデータがないのか、データは存在するが「column2='bbb'」には合致しなくて更新されないのかの切り分けをしたいのです。 かなり、困ってしまっています。 SQL文でできない場合でも、何かしらの解決方法がありましたら、よろしくお願いいたします!!!

  • Oracle SQLの、where句内の条件文について教えてください。

    Oracle SQLの、where句内の条件文について教えてください。 下記SQLの(1)と(2)の記述文を教えてください。 (1)例:owner = sys,admin ownerがsysまたは、adminを抽出 (2)例:column_name = '*aaa*' column_nameに「aaa」が含まれているデータ SELECT owner, table_name,column_name FROM all_tab_columns WHERE (1)(Ownerを複数指定)   and (2)(column_nameに、●●が含まれるデータ)

  • WHERE句の内部でWHEN

    いつもお世話になっております。 初歩的な質問で申し訳ありません。 SELECT X.COLA, X.COLB, Y.COLC FROM TABLE_X X, TABLE_Y Y WHERE X.COLA = Y.COLC AND WHEN X.COLB = "HOGEHOGE" THEN X.COLA > 100 ELSE X.COLA < 99; 以上のように COLBがある条件を満たす場合のみ、 WHERE句の条件を変更したいのですが、 上記の記述でよろしいのでしょうか? 現在手元にテストをできる環境が無い為、 初心者なりに机上で考えたのですが、 どなたかご教授いただければ幸いです。 よろしくお願い致します。

    • ベストアンサー
    • MySQL
  • PHP埋め込みのMySQLでwhere句が上手くいかない

    PHPのモジュールにMySQLのSELECT文を埋め込み、 where句でデータベースからデータを読込もう としています。 ところが、下記select文のand以下が無視され、 where句で指示した通りの結果が出ません。 文法的におかしいのでしょうか? どなたかアドバイスいただければ幸いです。 条件などは下記の通りです。 環境: OS Fedora Core5 MySQL 5.0.27 PHP 5.1.6 select文 "SELECT * FROM wrma_tbl where mise_id = $mise_code and (enddate is NULL) or (enddate > $maedate)" select文の説明: (1)DBの支店id(mise_id)と入力された支店code(mise_code)が一致すること…これは問題ない (2)作業終了日付(enddate)がNULLはピックアップする (3)作業終了日付(enddate)が今日(dateで抽出、yyyy-mm-dd)から30日前(maedate←正規の関数で計算済み)以前をオミット

  • VIEWに対してWHERE句をつける

    SQLでVIEWを作成し、そのVIEWに対してSELECT文を書くときに、そのVIEWに対してWHERE句をつけるのは、パフォーマンスを必ず下げることになるのでしょうか?勝手な認識ですが、VIEWにWHERE句をつけると遅くなる場合があると聞きました。VIEWの組み方にももちろんよると思いますが、VIEWは消極的に使い、出来る限りJOINなどして結合したSQLを書くほうが無難なのでしょうか?よろしくお願いいたします。

  • SQL WHERE句 分岐?

    SQL Server 2005 を使っております。 WHERE句の分岐といいますか、記述の方法がわからないのですが、下記がその部分になります。 下記のコードを実行すると、都道府県、血液型、両方に何かしらのデータが入っているものしか抽出してきません。都道府県、血液型、どちらかの値がNullの場合でも、どちらかの条件が合致していれば、抽出したいのですが、どう記述すればよろしいでしょうか? 下記のコードが Null = Null を認識していれば このコードでも抽出してくるんでしょうが、 Null = Null だと抽出しないんですね。 何卒よろしくお願いいたします。 WHERE (IsNull(@A,dbo.テスト.都道府県) = dbo.テスト.都道府県) AND (IsNull(@B,dbo.テスト.血液型) = dbo.テスト.血液型