0

これら 2 つのクエリの違いは何でしょうか?

投稿は確かにほとんどコードです。

SELECT DISTINCT S.name 
FROM 
    student S NATURAL JOIN taking NATURAL JOIN 
    (select * from class where classnum ='121') 
WHERE 
    department='CMPSC' 
    AND semester='Spring 2013';



SELECT DISTINCT S.name 
FROM 
    student S NATURAL JOIN taking NATURAL JOIN class 
WHERE 
    department='CMPSC' 
    AND semester='Spring 2013' 
    AND classnum='121';

ありがとうございました!

編集:

説明コマンドのリクエストへの応答として: ORACLE で実行する必要があったため、これが期待される結果であるかどうかはわかりません。

これは最初のクエリです。

Plan hash value: 3259400360

------------------------------------------------------
| Id  | Operation                     | Name         |
------------------------------------------------------
|   0 | SELECT STATEMENT              |              |
|   1 |  HASH UNIQUE                  |              |
|   2 |   NESTED LOOPS                |              |
|   3 |    NESTED LOOPS               |              |
|   4 |     TABLE ACCESS FULL         | CLASS        |
|   5 |     INDEX FULL SCAN           | SYS_C0099014 |
|   6 |    TABLE ACCESS BY INDEX ROWID| STUDENT      |
|   7 |     INDEX UNIQUE SCAN         | SYS_C0098998 |
------------------------------------------------------

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

   4 - filter("CLASSNUM"=121 AND "CLASS"."SEMESTER"='Spring 2013' AND
              "CLASS"."DEPARTMENT"='CMPSC')

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
   5 - access("TAKING"."SCHEDULENUM"="CLASS"."SCHEDULENUM" AND
              "TAKING"."SEMESTER"='Spring 2013')
       filter("TAKING"."SEMESTER"='Spring 2013' AND
              "TAKING"."SCHEDULENUM"="CLASS"."SCHEDULENUM")
   7 - access("S"."STUDENTNUM"="TAKING"."STUDENTNUM")

2 番目のクエリ:

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 226170808

-------------------------------------------------------
| Id  | Operation                      | Name         |
-------------------------------------------------------
|   0 | SELECT STATEMENT               |              |
|   1 |  HASH UNIQUE                   |              |
|   2 |   HASH JOIN                    |              |
|   3 |    MERGE JOIN                  |              |
|   4 |     TABLE ACCESS BY INDEX ROWID| STUDENT      |
|   5 |      INDEX FULL SCAN           | SYS_C0098998 |
|   6 |     SORT JOIN                  |              |
|   7 |      INDEX FULL SCAN           | SYS_C0099014 |
|   8 |    TABLE ACCESS FULL           | CLASS        |
-------------------------------------------------------

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

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------

   2 - access("TAKING"."SEMESTER"="CLASS"."SEMESTER")
   6 - access("S"."STUDENTNUM"="TAKING"."STUDENTNUM")
       filter("S"."STUDENTNUM"="TAKING"."STUDENTNUM")
   7 - access("TAKING"."SEMESTER"='Spring 2013')
       filter("TAKING"."SEMESTER"='Spring 2013')
   8 - filter("CLASS"."CLASSNUM"=121 AND "CLASS"."SEMESTER"='Spring 2013' AND
              "CLASS"."DEPARTMENT"='CMPSC')
4

1 に答える 1

0

パフォーマンスが問題である場合、それはインデックス作成を無効にしていることが原因です。サブクエリが実行されると、サーバーはインデックスを使用して結果を取得できます。ただし、サブクエリの結果をインデックス化できないため、パフォーマンスが低下します。一般的に言えば、オプティマイザーを「出し抜く」試みはうまく機能しません。つまり、読みにくいクエリになってしまい、まったく同じことを行うことになります (オプティマイザーはクエリを元のクエリと同じものに最適化します)。パフォーマンスが低下するこのようなケースになります。JOIN 句は、データを制約するのではなく、結合を定義するために使用する必要があります。

オプティマイザーは、次のクエリを同じように実行します。

SELECT *
FROM foo f
  JOIN bar b
    ON f.id = b.id
      AND b.col = 'baz'

SELECT *
FROM foo f
  JOIN bar b
    ON f.id = b.id
WHERE b.col = 'baz'

一方

SELECT *
FROM foo f
  JOIN (
    SELECT *
    FROM bar b
    WHERE col = 'baz'
  ) AS b
  ON f.id = b.id

基本的に、mysql でインデックスのないインメモリ一時テーブルを生成します。これは、SQL Server の前の 2 つと同じように実行されます。

于 2013-03-11T04:15:23.127 に答える