我希望这个问题已被多次提出,并且有不同的曲折。我想尝试对这个主题进行一般性和全面的了解。 (它属于编程SO吗?..)
假设我有sports
的表格和matches
的表格。 matches
,其他字段中有sport_id
列,这是1:多关系。
让我们说我想列出在第X天有比赛的运动。我可以用我能想到的三种方式来做这件事。
嵌套查询 - 很容易理由?
SELECT *
FROM sports
WHERE id IN (SELECT sport_id FROM matches WHERE <DATE CHECK>)
从/哪里 - 容易写?
SELECT sports.*
FROM sports, matches
WHERE sports.id = matches.sport_id
AND <DATE CHECK>
加入 - 我不太熟悉,所以原谅任何错误
SELECT *
FROM sports
JOIN matches ON sports.id = matches.sport_id
WHERE <DATE CHECK>
可能还有其他基于Join变体的方法,这可能更适合这里,也许是内连接..
我想知道的是如何在
的基础上比较这3个答案 0 :(得分:2)
第二个和第三个表单完全等效(除了第三个版本中有额外的逗号)。 FROM sports, matches
是隐式加入,FROM sports JOIN matches
是显式加入。隐式连接是早期的形式,显式连接更现代,通常是数据库专家首选。
WHERE IN
版本几乎相同,但存在一些差异。首先,SELECT *
将返回联接中两个表的列,但只返回sports
查询中WHERE IN
的列。其次,如果sports
中的一行与matches
中的多行匹配,则每个匹配对的连接将返回一行(它执行交叉产品),而WHERE IN
将返回无论有多少匹配,都会从sports
开一行。
性能差异取决于实现。显式和隐式连接之间不应该有任何区别,它们只是语法糖。但是,数据库并不总是优化WHERE IN
个查询。例如,当我将EXPLAIN
与MySQL一起使用时,WHERE IN
查询通常会对外部表执行完全扫描,将列与子查询中的表的索引进行匹配,即使子查询可能只返回少量行。我想有些人告诉我最近的MySQL版本更好。
他们将只是一个网络电话。所有查询只是对数据库服务器的一次调用。
顺便说一句,还有一个你没有列出的表格,使用带有相关子查询的WHERE EXISTS
。
SELECT *
FROM sports s
WHERE EXISTS (SELECT 1
FROM matches m
WHERE s.id = m.sport_id AND <DATE CHECK>)
此与JOIN
之间的效果差异将再次依赖于实现。
答案 1 :(得分:2)
以下是我对您的问题的看法
1.等效响应(返回相同的行?)
IN
Oprator我的回答是NO(你得到的行数相同但只有表sports
中的列)
第二和第三几乎相同2.数据库性能
首先在Oprator中较慢然后加入beacause 对于a中的每一行,评估IN(以及从b重新运行中选择),而JOIN被优化为使用索引和其他整齐的分页技巧......
ANSI JOIN语法
SELECT fname, lname, department
FROM names INNER JOIN departments ON names.employeeid = departments.employeeid
前Microsoft JOIN语法
SELECT fname, lname, department
FROM names, departments
WHERE names.employeeid = departments.employeeid
如果写得正确,任何一种格式都会产生相同的结果。但这是一个很大的问题。较旧的Microsoft join语法会导致错误,因为语法不太明显。另一方面,ANSI语法非常明确,你很可能犯错误。
3.所有这些都是1个查询/网络电话或?
- IN
- Microsoft JOIN
,
- ANSI JOIN
的'trial 3结果
4.这些答案是否与db引擎相关?
(抱歉,这个问题我得到了答案)
5.我如何选择?
我建议你使用ANSI JOIN
6.#3是#2的#2语法糖?是#1?或者它们在某些/所有情况下都被优化为#3
- 我认为没有,正如我上面提到的#3 syntex更为重要 根据我过去的经验 我在ERP程序中遇到了一个执行缓慢的查询。在查看使用Microsoft JOIN语法的代码之后,我注意到开发人员不小心创建了一个CROSS JOIN而不是创建LEFT JOIN。在此特定示例中,LEFT JOIN应该产生少于10,000行,但由于使用了CROSS JOIN,因此返回了超过1,100万行。然后开发人员使用SELECT DISTINCT来删除CROSS JOIN创建的所有不必要的行。你可以猜到,这是一个非常冗长的查询。我通知了供应商的支持部门,他们修改了代码。
这个故事的寓意是你可能应该使用ANSI语法,而不是旧的Microsoft语法。除了减少制造愚蠢错误的几率外,这段代码在数据库之间更容易移植,最终,我想微软最终将停止支持旧格式,使ANSI语法成为唯一的选择