什么可能使这两个查询不同?
帖子确实主要是代码。
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';
谢谢!
编辑:
作为对explain命令请求的响应:我必须在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")
第二个QUERY:
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')
答案 0 :(得分: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中执行与前两个相同的操作。