1

他们做同样的事情,但我想知道是否有一些区别,我的意思是关于性能......

TB1:tb1_id -> PK ...

TB2:tb1_id -> FK ...

select columns ... from tb1 a left join tb2 b
    on a.tb1_id=b.tb1_id and b.uid=xxxxxxx where a.tb1_id=yyy limit 1

select columns ... from tb1 a left join tb2 b
    on a.tb1_id=b.tb1_id where a.tb1_id=yyy and b.uid=xxxxxxx limit 1

谢谢。

4

4 回答 4

2

稍微简化一下,您可以认为JOIN首先评估您的 s ,然后WHERE应用 s 过滤器。使用这个公式:

1)您的第一个查询将返回表中的所有记录和表中a的相应记录b(如果存在,否则为一组NULLs),这些记录在字段中具有匹配tb1_id和特定值uid。然后,结果集将被过滤为只有记录a.tb1_id=yyy和第一条记录返回给客户端。

2)您的第二个查询将返回 table 中的所有记录以及 table中具有匹配的a相应记录b(如果存在,否则为一组s) 。结果集将被过滤掉,只包含具有特定值 in和特定值 in 的记录。最后一部分很重要。此特定条件将丢弃表中没有匹配集的所有记录,因为. 本质上,您不会将 a. 当您这样做时,您会立即将您的join 转换为one。剩余集合的第一条记录将返回给客户端。NULLtb1_ida.tb1_idb.uidabNULL != xxxxxxxLEFT JOINWHEREOUTERINNER

也就是说,在您的情况下,您可能会得到相同的结果。巧合的是。您的查询中没有ORDER BY,因此返回的记录顺序取决于数据库引擎(您最好认为它不是确定性的,不能依赖,它很可能是这样的),它只是可能碰巧两个查询返回的第一条记录是匹配所有条件的记录-在和中都有tb1_id匹配项,在.abxxxxxxxb.uid

于 2012-05-31T02:36:06.353 回答
1

他们不一样。请参阅@Pavel_Veller 提供的答案这只是为了支持他的答案。在 Postgres 上运行:

create table tb1( tb1_id int );
create table tb2( tb1_id int, uid int );

insert into tb1 values( 1 );

insert into tb2 values( 1, 0 );

select a.tb1_id
  from tb1 a left join tb2 b on a.tb1_id = b.tb1_id and b.uid = 3
  where a.tb1_id = 1;

select a.tb1_id
  from tb1 a left join tb2 b on a.tb1_id = b.tb1_id
  where a.tb1_id = 1
    and b.uid = 3;

结果:

postgres=#     select a.tb1_id
postgres-#       from tb1 a left join tb2 b on a.tb1_id = b.tb1_id and b.uid = 3
postgres-#       where a.tb1_id = 1;
 tb1_id
--------
      1
(1 row)


postgres=#     select a.tb1_id
postgres-#       from tb1 a left join tb2 b on a.tb1_id = b.tb1_id
postgres-#       where a.tb1_id = 1
postgres-#         and b.uid = 3;
 tb1_id
--------
(0 rows)
于 2012-05-31T03:02:27.360 回答
1

在没有注意到 JOIN 的“LEFT”部分之后,我怀疑我原来的答案。经过一些快速研究,我修改了我的答案。

这篇文章详细解释了事情,表明查询实际上是不同的。

下面的文章中的示例显示了这一点。

mysql> SELECT * FROM product LEFT JOIN product_details
   ON (product.id = product_details.id)
   AND product_details.id=2;
+----+--------+------+--------+-------+
| id | amount | id   | weight | exist |
+----+--------+------+--------+-------+
|  1 |    100 | NULL |   NULL |  NULL |
|  2 |    200 |    2 |     22 |     0 |
|  3 |    300 | NULL |   NULL |  NULL |
|  4 |    400 | NULL |   NULL |  NULL |
+----+--------+------+--------+-------+
4 rows in set (0.00 sec)

mysql> SELECT * FROM product LEFT JOIN product_details
   ON (product.id = product_details.id)
   WHERE product_details.id=2;
+----+--------+----+--------+-------+
| id | amount | id | weight | exist |
+----+--------+----+--------+-------+
|  2 |    200 |  2 |     22 |     0 |
+----+--------+----+--------+-------+
1 row in set (0.01 sec)
于 2012-05-31T02:40:45.147 回答
0

这两个查询根本不做同样的事情,第一个查询可能不会从 b 返回任何行,而第二个查询不会从 a 或 b 返回任何行,如果没有与 b 的有效连接。

Mysql 将 where 子句中的“=”解释为一个 INNER 连接(它不是一个连接,但在这种情况下它的使用方式相同)

于 2012-05-31T01:28:49.913 回答