加入vs加入类似查询 - 它们是否相同?

时间:2014-06-28 05:15:04

标签: sql performance join

我希望这个问题已被多次提出,并且有不同的曲折。我想尝试对这个主题进行一般性和全面的了解。 (它属于编程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个
  1. 等效响应(返回相同的行?)
  2. 数据库性能
  3. 他们都是1个查询/网络电话或?
  4. 这些答案是否与数据库引擎有关?
  5. 我如何选择?
  6. #3是#2的#2语法糖?是#1?或者它们在某些/所有情况下都被优化为#3?

2 个答案:

答案 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.等效响应(返回相同的行?)

  • 对于你使用过的第一个QUERY 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

的结果1结果

- Microsoft JOIN

的结果2

- ANSI JOIN的'trial 3结果 enter image description here 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语法成为唯一的选择