顧名思義, 這個概念得名於笛卡兒. 在數學中,兩個集合 X 和 Y 的笛卡兒積(Cartesian product),又稱直積,表示爲 X × Y,是其第一個對象是 X 的成員而第二個對象是 Y 的一個成員的全部可能的有序對.sql
假設集合A={a,b},集合B={0,1,2},則兩個集合的笛卡爾積爲{(a,0),(a,1),(a,2),(b,0),(b,1), (b,2)}。能夠擴展到多個集合的狀況。相似的例子有,若是A表示某學校學生的集合,B表示該學校全部課程的集合,則A與B的笛卡爾積表示全部可能的選課狀況。app
2.Join類型 ide
cross join 是笛卡兒乘積就是一張表的行數乘以另外一張表的行數.
inner join 只返回兩張錶鏈接列的匹配項.
left join 第一張表的鏈接列在第二張表中沒有匹配是,第二張表中的值返回null.
right join 第二張表的鏈接列在第一張表中沒有匹配是,第一張表中的值返回null.
full join 返回兩張表中的行 left join+right join.
3.在對兩表進行各類類型的join (cross, left, right, full, inner)時, 都須要構造笛卡爾積.post
有時想一想難以想象, 若兩個特大表進行join, 難道sql就直接上笛卡爾積嗎? 難道不事前進行on的條件過濾嗎? 那數據量得多大?大數據
4.查一下MSDN就清楚了整個SQL的執行順序.翻譯
http://msdn.microsoft.com/en-us/library/ms189499(v=SQL.100).aspxhtm
Processing Order of the SELECT statement
The following steps show the processing order for a SELECT statement.對象
1.FROMblog
2.ONget
3.JOIN
4.WHERE
5.GROUP BY
6.WITH CUBE or WITH ROLLUP
7.HAVING
8.SELECT
9.DISTINCT
10.ORDER BY
11.TOP
也就是說, 先進行on的過濾, 然後才進行join, 這樣就避免了兩個大表產生所有數據的笛卡爾積的龐大數據.
這些步驟執行時, 每一個步驟都會產生一個虛擬表,該虛擬表被用做下一個步驟的輸入。這些虛擬表對調用者(客戶端應用程序或者外部查詢)不可用。只是最後一步生成的表纔會返回 給調用者。
若是沒有在查詢中指定某一子句,將跳過相應的步驟。
下面是<<Inside Microsoft SQL Server 2008 T-SQL Querying>>一書中給的一幅SQL 執行順序的插圖.
5.On的其他過濾條件放Where裏效率更高仍是更低?
select * from table1 as a
inner join table2 as b on a.id=b.id and a.status=1
select * from table1 as a
inner join table2 as b on a.id=b.id
where a.status=1
查查MSDN就清楚了. http://msdn.microsoft.com/en-us/library/ms189499(v=SQL.100).aspx
There can be predicates that involve only one of the joined tables in the ON clause. Such predicates also can be in the WHERE clause in the query. Although the placement of such predicates does not make a difference for INNER joins, they might cause a different result when OUTER joins are involved. This is because the predicates in the ON clause are applied to the table before the join, whereas the WHERE clause is semantically applied to the result of the join.
翻譯以後是, 若是是inner join, 放on和放where產生的結果同樣, 但沒說哪一個效率速度更高? 若是有outer join (left or right), 就有區別了, 由於on生效在先, 已經提早過濾了一部分數據, 而where生效在後.
綜合一下, 感受仍是放在on裏更有效率, 由於它先於where執行.
據說能夠經過sql的查詢計劃來判別實際的結果, 明天再研究, 歡迎高手給與批評指正.
********************************************************************************************************
2011/11/21 最新體會
剛看到<<Microsoft SQL Server 2008技術內幕: T-SQL查詢>>一書中對於鏈接的描述和我先前理解的不太同樣;
Itzib在書上說先笛卡爾積, 而後再on過濾, 若是join是inner的, 就繼續往下走, 若是join 是left join, 就把on過濾掉的左主表中的數據再添加回來; 而後再執行where裏的過濾;
on中不是最終過濾, 由於後面left join還可能添加回來, 而where纔是最終過濾.
只有當使用外鏈接(left, right)時, on 和 where 纔有這個區別, 若是用inner join, 在哪裏制定都同樣, 由於on 以後就是where, 中間沒有其它步驟.