0

什么可能使这两个查询不同?

该帖子确实主要是代码。

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")

第二个查询:

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 中的前两个执行相同。

于 2013-03-11T04:15:23.127 回答