2012-05-31 49 views
1

他們做同樣的事情,但我想知道是否有一些差別,我的意思是有關性能...這些SQL查詢有一些區別嗎?

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 

感謝。

回答

0

這兩個查詢根本不會做同樣的事情,第一個可能不會返回任何來自b的行,而第二個不會返回任何來自a和b的任何行,如果沒有與b的有效連接。

Mysql的interpretes中的「=」 where子句,就好像它是一個INNER JOIN(它不是加入,但它是用來在這種情況下,以同樣的方式)

2

簡化的東西一點點就可以認爲你的JOIN先評估,然後應用WHERE的過濾器。使用這個公式:

1)你的第一個查詢將返回從表a從表b所有記錄和相應的記錄(如果存在的,否則一組NULL S)具有匹配tb1_id並在uid領域一定值。然後將結果集過濾爲僅具有a.tb1_id=yyy的記錄,並將第一條記錄返回給客戶端。

2)你的第二個查詢將返回所有記錄表a和相應的從表b記錄(如果存在的,否則一組NULL S)具有匹配tb1_id。結果集將被過濾掉,只有在a.tb1_id中具有特定值的記錄以及b.uid中的某個值。最後一部分很重要。這種特殊情況將丟棄表a中的所有記錄,這些記錄在b中沒有匹配的集合,只是因爲NULL != xxxxxxx。本質上,你不會混合LEFT JOINWHERE中的「硬」條件。當你這樣做時,你立即轉換您的OUTER加入INNER。剩餘集合的第一條記錄將返回給客戶端。

也就是說,這可能會發生在你的情況下,你可能會得到相同的結果。無獨有偶。您的查詢中沒有ORDER BY,因此返回的記錄順序取決於數據庫引擎(您最好認爲它不是確定性的,不能依賴,它很可能是如此),它只是可能會發生這樣的情況,即兩個查詢返回的第一條記錄是匹配所有條件的第一條記錄 - 在ab以及b.uid中的xxxxxxxtb1_id匹配。

1

在沒有注意到JOIN的'LEFT'部分後,我懷疑我的原始答案。經過一些快速的研究,我修改了我的答案。

article詳細解釋了事情,表明查詢實際上處理方式不同。

這是用下面的文章中的一個例子顯示的。

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) 
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)