MySql在内部连接中哪个表先到有关系吗?
我正在选择数据以输出用户已标记书本的帖子 保存用户已添加书签的MySql在内部连接中哪个表先到有关系吗?,mysql,sql,Mysql,Sql,我正在选择数据以输出用户已标记书本的帖子 保存用户已添加书签的posts的ids的主表称为bookMarks。这是将从posts表中选择要显示给用户的posts所基于的表 书签 id | postId | userId -------------------------- 1 | US01 | 1 2 | US02 | 1 3 | US01 | 2 4 | US02 | 2 id | postId | postTitle
posts
的id
s的主表称为bookMarks
。这是将从posts
表中选择要显示给用户的posts
所基于的表
书签
id | postId | userId
--------------------------
1 | US01 | 1
2 | US02 | 1
3 | US01 | 2
4 | US02 | 2
id | postId | postTitle
--------------------------
1 | US01 | Title 1
2 | US02 | Title 2
3 | US03 | Title 3
4 | US04 | Title 4
帖子
id | postId | userId
--------------------------
1 | US01 | 1
2 | US02 | 1
3 | US01 | 2
4 | US02 | 2
id | postId | postTitle
--------------------------
1 | US01 | Title 1
2 | US02 | Title 2
3 | US03 | Title 3
4 | US04 | Title 4
我的sql当前是这样的:
select a.postsTitle
from posts a
inner join bookmarks b
on b.userId = a.userId
and b.userId = :userId
注意,我将表posts
放在表书签之前。但是,由于我是根据书签
中的内容进行选择的,是否有必要先声明表书签
,而不是在sql语句中声明post
?我这样做会不会导致数据选择或效率方面的问题
或者我应该这样做:
select b.postsTitle
from bookmarks a
inner join posts b
on a.userId = b.userId
and a.userId = :userId
请注意,我将表书签放在这里的第一位。如果使用了内部联接,则在联接子句的任一侧放置表不会影响查询性能或最终结果集
观察到的唯一区别是返回的列的顺序,只有在使用了SELECT*
的情况下,这种差异才会太大。假设您有tableA(aid,col1,col2)和tableB(bid,col3)
按顺序返回列
aid|col1|col2|bid|col3
bid|col3|aid|col1|col2|
另一方面
SELECT *
FROM tableB
INNER JOIN tableA
ON tableA.aid=tableB.bid
按顺序返回列
aid|col1|col2|bid|col3
bid|col3|aid|col1|col2|
但在左连接或右连接而不是以下情况下,它很重要:
select a.postsTitle
from posts a
inner join bookmarks b
on b.userId = a.userId
and b.userId = :userId
SELECT *
FROM bookmarks b
INNER JOIN posts p
ON p.userId = b.userId
WHERE b.userId = :userId
SELECT p.*, b.*
FROM bookmarks b
INNER JOIN posts p
ON p.userId = b.userId
WHERE b.userId = :userId
您应该考虑以这种格式格式化您的连接,使用<代码>其中子句,以及适当的大写:
SELECT p.postsTitle
FROM bookmarks b
INNER JOIN posts p
ON p.userId = b.userId
WHERE b.userId = :userId
虽然使用内部联接将表放入哪个顺序对MySQL没有影响(性能方面)(MySQL将它们视为相等的,并将以相同的方式对它们进行优化),但按照惯例,将应用WHERE
子句的表放在第一位。事实上,假设索引正确,MySQL最有可能从包含WHERE
子句的表开始,因为它缩小了结果集的范围,而MySQL喜欢从行数最少的表开始
在ON子句中,将联接表的列放在第一位也是惯例。它读起来更符合逻辑。在进行此操作时,请使用逻辑表别名
唯一需要注意的是,如果您不命名列,而是使用SELECT*
,如下所示:
select a.postsTitle
from posts a
inner join bookmarks b
on b.userId = a.userId
and b.userId = :userId
SELECT *
FROM bookmarks b
INNER JOIN posts p
ON p.userId = b.userId
WHERE b.userId = :userId
SELECT p.*, b.*
FROM bookmarks b
INNER JOIN posts p
ON p.userId = b.userId
WHERE b.userId = :userId
您将按照列在查询中列出的顺序获得这些列。在本例中,您将获得书签
的列,然后是帖子
的列
大多数人会说绝不在生产查询中使用SELECT*
,但如果您确实必须返回所有列,并且首先需要posts
中的列,您可以简单地执行以下操作:
select a.postsTitle
from posts a
inner join bookmarks b
on b.userId = a.userId
and b.userId = :userId
SELECT *
FROM bookmarks b
INNER JOIN posts p
ON p.userId = b.userId
WHERE b.userId = :userId
SELECT p.*, b.*
FROM bookmarks b
INNER JOIN posts p
ON p.userId = b.userId
WHERE b.userId = :userId
明确返回的结果集总是好的。Hmm。。。感谢您澄清这一点。除了m hasan的回答之外,按照惯例,where子句可能只在一个表上放置条件,我们倾向于先放置该表,然后将其他表加入其中。但这只是一种惯例,对内部连接的性能没有影响。这是否回答了你的问题?在我的问题中,和
就是a的实际位置。我打错了。@Marcus Adams您是否有任何证据支持内部联接顺序不重要的情况。我一直在尝试查找引用,但找不到任何引用。@Nap,-“对于只涉及内部联接(而不涉及外部联接)的联接表达式,可以删除括号并从左到右计算联接。事实上,表可以按任何顺序计算。”