Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 使用相关子查询比使用联接好吗?(索引透视图)_Mysql_Sql_Join_Indexing_Subquery - Fatal编程技术网

Mysql 使用相关子查询比使用联接好吗?(索引透视图)

Mysql 使用相关子查询比使用联接好吗?(索引透视图),mysql,sql,join,indexing,subquery,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.*, (SELECT 1 FROM mytable2 m2 WHERE col2 = ?) AS sth
FROM mytable1 m1 WHERE col1 = ?
上面的查询可以使用两个索引:
mytable1(col1)
mytable2(col2)
。因为是两个分开的查询

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


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

这对于注释来说太长了

这两个查询在多个方面是不同的:

  • 第一个返回
    mytable1
    中与
    where
    条件匹配的所有行,而不管第二个表中是否存在匹配项。第二个仅返回匹配的行
  • 如果子查询返回多行,则第一个查询将失败并出错。第二个返回多个匹配的行
  • 因此,对于
    sth
    ,第一个可以返回
    NULL
    ,第二个不能
我的建议是首先学习编写满足功能需求的查询。然后担心性能


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

一般来说,这一切都取决于。最后,SQLServer将创建执行计划,根据它对查询的解释方式,一个可能比另一个更好。话虽如此,一般来说,加入更好

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

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

因此,在本例中,它可以使用两个索引:mytable1(col1)和mytable2(col2)

如果执行自连接、联合或子查询,甚至可以从同一个表中使用两个不同的索引。每次引用该表时,该表都算作单独的表引用

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

不管索引如何,这都是一个奇怪的查询。您没有将mytable1与mytable2关联的条件。你在两张桌子之间做笛卡尔积。根据col1和col2的条件,一个或两个表可能正在选择一行。但它仍然是笛卡尔积,因此,如果两个表上的条件都返回多行,您将得到大量重复的结果集。

索引的使用由查询优化器引擎评估,并与联接表一起使用。.重写示例以避免答案中描述的陷阱。然后提供
解释选择用于每个。然后我们可以讨论你想问的问题。谢谢。。但是你的解释就是我两个问题之间的区别。。好吧,我明白了,我无法根据子查询正确地模拟联接。但是索引呢?子查询使用更好的索引或连接?@MartinAJ:MySQL在这两种情况下都可以有效地使用索引。正如Gordon所说,这两个查询返回的结果根本不同,在特殊条件下可能恰好相同。当子查询位于选择列表中时,如果子查询返回多行,则查询将抛出错误。在联接查询中,如果在
m2
中找不到任何行,查询将不会返回任何行。首先定义您希望在什么条件下返回什么结果。
col2
是否保证是唯一的?。(对戈登来说,+10,冒着得罪老太太的风险。)@MartinAJ。您的两个查询不同。一个符合需要,回答需要回答的问题。那是你应该用的。在获得正确的查询后,如果需要,您可以解决性能问题。
SELECT m1.*, m2.1 AS sth
FROM mytable1 m1
JOIN mytable2 m2 ON m2.col2 = ?
WHERE m1.col1 = ?