使用相关子查询比加入更好吗? (索引透视)

时间:2017-02-10 19:21:27

标签: mysql sql join indexing subquery

我读到了类似这样的地方:

  

每个查询都将使用索引。

如您所知,这是两个查询

SELECT m1.*, (SELECT 1 FROM mytable2 m2 WHERE col2 = ?) AS sth
FROM mytable1 m1 WHERE col1 = ?

上面的查询可以使用两个索引:mytable1(col1)mytable2(col2)。因为是两个分开的查询。

现在看看这个:(与之前的查询相同,只使用join而不是子查询)

SELECT m1.*, m2.1 AS sth
FROM mytable1 m1
JOIN mytable2 m2 ON m2.col2 = ?
WHERE m1.col1 = ?

但是这个^查询只是一个查询。所以它只能使用一个索引。我的理解是对的吗?所以使用子查询更适合索引,对吧?

3 个答案:

答案 0 :(得分:2)

  

但是这个^查询只是一个查询。所以它只能使用一个索引。我的理解是对的吗?所以使用子查询更适合索引,对吧?

你误解了。 MySQL可以使用一个索引每个表引用

所以在这种情况下,它可以使用两个索引:mytable1(col1),mytable2(col2)。

如果您执行自联接或UNION或子查询,您甚至可以使用相同表中的两个不同索引。每次引用表计数作为单独的表引用时。

SELECT m1.*, m2.1 AS sth
FROM mytable1 m1
JOIN mytable2 m2 ON m2.col2 = ?
WHERE m1.col1 = ?

无论索引如何,这都是一个奇怪的查询。您没有将mytable1与mytable2相关联的条件。所以你在两张桌子之间做笛卡尔积。一个或两个表可能正在选择单行,具体取决于col1和col2的条件。但它仍然是笛卡尔积,所以如果两个表上的条件都返回多行,那么你将得到大量重复的结果集。

答案 1 :(得分:1)

评论太长了。

这两个查询在多个方面有所不同:

  • 第一个返回mytable1中与where条件匹配的所有行,无论第二个表中是否匹配。第二个只返回匹配的行。
  • 如果子查询返回多行,则第一个失败并显示错误。第二个返回多个匹配的行。
  • 因此,第一个可以返回NULL sth,第二个不能返回。{/ li>

我的建议是首先学会编写满足您功能需求的查询。然后担心表现。

至于你的问题,相关的子查询和连接都可以使用索引。相关子查询总是比连接更糟糕的想法是一个老妻子的故事(对老妻子没有冒犯)应该被遗忘。

答案 2 :(得分:0)

一般来说,一切都取决于。在一天结束时,SQL Server将创建执行计划,并且根据它如何解释您的查询,一个可能比另一个更好。说到这一点,通常情况下,加入更好。