16

where句に次のような一連の条件があります

WHERE 
d.attribute3 = 'abcd*'  
AND x.STATUS != 'P' 
AND x.STATUS != 'J' 
AND x.STATUS != 'X' 
AND x.STATUS != 'S' 
AND x.STATUS != 'D' 
AND CURRENT_TIMESTAMP - 1 < x.CREATION_TIMESTAMP

これらの条件のうち、最初に実行されるのはどれですか? オラクルを使用しています。

実行計画でこれらの詳細を取得できますか? (私はここのデータベースでそれを行う権限を持っていません、そうでなければ私は試したでしょう)

4

6 に答える 6

22

実行計画を表示する「権限がありません」でよろしいです? AUTOTRACE の使用についてはどうですか?

SQL> set autotrace on
SQL> select * from emp
  2  join dept on dept.deptno = emp.deptno
  3  where emp.ename like 'K%'
  4  and dept.loc like 'l%'
  5  /

no rows selected


Execution Plan
----------------------------------------------------------

----------------------------------------------------------------------------------
| Id  | Operation                    | Name         | Rows  | Bytes | Cost (%CPU)|
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |              |     1 |    62 |     4   (0)|
|   1 |  NESTED LOOPS                |              |     1 |    62 |     4   (0)|
|*  2 |   TABLE ACCESS FULL          | EMP          |     1 |    42 |     3   (0)|
|*  3 |   TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)|
|*  4 |    INDEX UNIQUE SCAN         | SYS_C0042912 |     1 |       |     0   (0)|
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("EMP"."ENAME" LIKE 'K%' AND "EMP"."DEPTNO" IS NOT NULL)
   3 - filter("DEPT"."LOC" LIKE 'l%')
   4 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")

ご覧のとおり、クエリがどのように実行されるかについて非常に多くの詳細が得られます。それは私にそれを教えてくれます:

  • EMP のフルスキャン時に、条件「emp.ename like 'K%'」が最初に適用されます。
  • 次に、一致する DEPT レコードが dept.deptno のインデックスを介して (NESTED LOOPS メソッドを介して) 選択されます。
  • 最後に、「l%」のようなフィルター「dept.loc」が適用されます。

この適用順序は、述語が WHERE 句で順序付けられる方法とは何の関係もありません。これは、次の並べ替えられたクエリで示すことができます。

SQL> select * from emp
  2  join dept on dept.deptno = emp.deptno
  3  where dept.loc like 'l%'
  4  and emp.ename like 'K%';

no rows selected


Execution Plan
----------------------------------------------------------

----------------------------------------------------------------------------------
| Id  | Operation                    | Name         | Rows  | Bytes | Cost (%CPU)|
----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |              |     1 |    62 |     4   (0)|
|   1 |  NESTED LOOPS                |              |     1 |    62 |     4   (0)|
|*  2 |   TABLE ACCESS FULL          | EMP          |     1 |    42 |     3   (0)|
|*  3 |   TABLE ACCESS BY INDEX ROWID| DEPT         |     1 |    20 |     1   (0)|
|*  4 |    INDEX UNIQUE SCAN         | SYS_C0042912 |     1 |       |     0   (0)|
----------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("EMP"."ENAME" LIKE 'K%' AND "EMP"."DEPTNO" IS NOT NULL)
   3 - filter("DEPT"."LOC" LIKE 'l%')
   4 - access("DEPT"."DEPTNO"="EMP"."DEPTNO")
于 2008-12-04T11:40:46.533 に答える
7

データベースは、条件を実行する順序を決定します。

通常は (常にではありませんが)、可能な場合は最初にインデックスを使用します。

于 2008-12-04T10:28:53.107 に答える
6

すでに述べたように、実行計画を見ると、いくつかの情報が得られます。ただし、計画安定機能を使用しない限り、実行計画が常に同じであるとは言えません。

あなたが投稿したクエリの場合、評価の順序によってロジックが変わるようには見えないので、あなたが考えているのは効率だと思います。Oracle オプティマイザが効率的な計画を選択する可能性はかなり高いです。

パフォーマンスを基本クエリと比較したい場合、特定の順序付けを促進するためにできるトリックがあります。たとえば、タイムスタンプ条件を最初に実行したいとします。あなたはこれを行うことができます:

WITH subset AS
  ( SELECT /*+ materialize */
      FROM my_table
      WHERE CURRENT_TIMESTAMP - 1 < x.CREATION_TIMESTAMP
  )
SELECT *
  FROM subset
  WHERE 
  d.attribute3 = 'abcd*'  
  AND x.STATUS != 'P' 
  AND x.STATUS != 'J' 
  AND x.STATUS != 'X' 
  AND x.STATUS != 'S' 
  AND x.STATUS != 'D'

「マテリアライズ」ヒントにより、オプティマイザは最初にインライン クエリを実行し、次にその結果セットをスキャンして他の条件を確認する必要があります。

これを一般的な習慣として行うことをお勧めしているわけではありません。ほとんどの場合、単純なクエリを記述するだけで最適な実行計画が得られます。

于 2008-12-04T15:13:28.147 に答える
1

実行計画に関する他のコメントに加えて、9iで導入され、デフォルトで10g以上で使用されるCPUベースの原価計算モデルでは、Oracleは、どの述語評価順序が計算コストの削減につながるかについても評価します。テーブルのアクセス順序と方法。ある述語を別の述語の前に実行すると、実行される述語計算が少なくなる場合は、その最適化を適用できます。

詳細については、次の記事を参照してください。http ://www.oracle.com/technology/pub/articles/lewis_cbo.html

さらに、Oracleは、チェック制約またはパーティション定義との比較により、いずれにせよ行が返されないことが示される述語を実行する必要さえありません。

複雑なもの。

于 2008-12-04T15:39:47.550 に答える
1

最後に、リレーショナル データベースの理論では、クエリ句の実行順序に依存することはできないため、実行しないことをお勧めします。他の人が言ったように、コストベースのオプティマイザは最適と思われるものを選択しようとしますが、Explain Planを表示しても、使用される実際の順序は保証されません。計画の説明は、CBO が何を推奨しているかを示しているだけですが、それでも 100% ではありません。

なぜこれをやろうとしているのかを説明すれば、計画を提案してくれる人もいるでしょうか?

于 2009-01-02T19:40:46.813 に答える