我读到了类似这样的地方:
每个查询都将使用索引。
如您所知,这是两个查询:
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 = ?
但是这个^查询只是一个查询。所以它只能使用一个索引。我的理解是对的吗?所以使用子查询更适合索引,对吧?
答案 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将创建执行计划,并且根据它如何解释您的查询,一个可能比另一个更好。说到这一点,通常情况下,加入更好。