聽了一堂SQL課,受益良多,做下筆記。
SQL語句的執(zhí)行計劃
慚愧啊,這個名詞我今天還是第一次接觸,這大概已經(jīng)是常識了吧呵呵。
沒有太深的研究,暫時想是這樣的,每一種數(shù)據(jù)庫服務(wù)器在執(zhí)行一條SQL語句的時候,首先都要解析這條SQL語句,每種數(shù)據(jù)庫服務(wù)器的解析方式是不一樣的,這樣,制定出來的執(zhí)行計劃也就是不一樣的。服務(wù)器通常都會在執(zhí)行前通過某種算法(優(yōu)化器)計算出很多種執(zhí)行計劃,然后選擇其中它認為是最優(yōu)的一種進行執(zhí)行。
學會查看SQL語句的執(zhí)行計劃,有助于清晰的理解SQL語句的執(zhí)行過程,特別是對SQL語句進行優(yōu)化的時候,會有很大的幫助。
外連接



如上所示,即左外連接,表示左邊的內(nèi)容有可能不全。當不全的時候,結(jié)果用空來代替。
理解外連接:相當于兩個循環(huán)嵌套。





全外連接,相當于左外連接和右外連接的并集。
子查詢
不相關(guān)子查詢:子查詢中,不涉及外層表中的數(shù)據(jù)。如:





不相關(guān)子查詢理解:先執(zhí)行子查詢,再執(zhí)行外層查詢。
相關(guān)子查詢:子查詢中,涉及到外層表中的數(shù)據(jù)。如:





相關(guān)子查詢理解:同樣是兩個循環(huán)的嵌套,如下:









PS: a.f1 = (select語句),這個屬于SQL3中的表表達式,select中可以返回多條記錄,Oracle中不支持這種寫法,所以當select語句返回多條記錄的時候,會報錯。但是DB2支持。
多行子查詢:子查詢返回多行記錄,一般和IN, ANY, ALL, EXISTS配合使用。如:





理解多行子查詢:a.f1會和子查詢結(jié)果中的每一個數(shù)據(jù)進行一次匹配循環(huán),所以,這里值得注意的是:
1. IN和EXISTS的執(zhí)行計劃正好相反。用IN時,子查詢?yōu)閮?nèi)層循環(huán),用EXISTS時,子查詢?yōu)橥鈱友h(huán)。
2. 用IN時,子查詢的返回條數(shù)不要太多,一般幾十個已經(jīng)夠多了,如果過百的話.....呵呵.....
Top-N查詢





這里有個值得注意的地方就是,一定要先排序,再取Top-N。兩個不要寫在一起。
PS: SQL服務(wù)器從來都不保證解析出來的數(shù)據(jù)是有次序的,雖然我們不寫ORDER BY查詢時,每次查詢結(jié)果的次序幾乎都是一樣的,但是,不能被表象所迷惑,這是不穩(wěn)定的次序。
游標
以前理解游標只是一種變量類型,如果把它看成是一種語句執(zhí)行方式的話,那么任何的SQL語句都是用游標的形式執(zhí)行的。
游標變量
1. Strong 類型,即強類型。也許是我接觸的比較少,還沒發(fā)現(xiàn)有什么用,該類型游標變量必須指定游標的類型,對游標的使用進行了限制。
2. Weak類型,即弱類型。經(jīng)常用,使用起來比較靈活,可以存儲任意的返回類型。既然靈活,我想,也許會多少占用一些內(nèi)存吧,還沒深入研究。
異常
預(yù)先知道的一些異常,最好不要寫在最后的異常捕獲里。
比如,SELECT a INTO b FROM c. 如果a為null的話,會報no data found異常。象這樣的,我們往往接受為null的情況,不想用異常來捕獲,可以用兩種方法來處理:
1. 使用游標
FETCH ... INTO...的時候,即使為空,也不會出異常,會繼續(xù)執(zhí)行下面的語句。
2. 使用PL/SQL塊
BEGIN
...
EXCEPTION
// 進行局部異常處理
END;
關(guān)于優(yōu)化
這個地方聽的我就很迷糊了,很多概念都很模糊,先記錄下。
任何一個SQL語句傳到數(shù)據(jù)庫的服務(wù)端都會被解析成一個執(zhí)行樹,每個節(jié)點是一個函數(shù)。
對表的處理只有兩種處理方式,全表掃描和使用索引。
當返回值達到N時,使用全表掃描,也就是把數(shù)據(jù)全讀到內(nèi)存中一一進行處理。這里N的值,很多因素影響,一直都有變化,曾經(jīng)是20%,可做參考。
當返回值小于N時,使用索引進行掃描。
索引就是一個B+樹,和表密切相關(guān)。在執(zhí)行delete操作的時候,索引并不被刪除,而是用某個標識標識無效,所以,當對某個有索引的表的insert,delete操作比較頻繁的時候,索引很有可能變得很龐大,這個時候就要考慮到對索引的維護。
這里索引的用法我還有很多地方迷惑,保留做以后研究。
歡迎來訪!^.^!
本BLOG僅用于個人學習交流!
目的在于記錄個人成長.
所有文字均屬于個人理解.
如有錯誤,望多多指教!不勝感激!