幾條Oracle資料庫開發的原則歸納(上)

realkid4發表於2011-08-22

 

目前絕大多數的MIS系統,都是基於對資料庫的互動式操作,開發人員大部分的工作都是直接或者間接與資料庫打交道。作為開發人員,正確的使用資料庫技術,不但可以提高資料庫相關開發的效率,而且可以有效的減少投產運維階段的工作量。本篇從筆者的實際工作體會入手,簡單介紹幾個Oracle相關開發原則。

 

1、  “Never Treate Database Like A blackbox”

 

絕不要將資料庫視為一個黑盒Oracle大師Thomas Kyte給所有資料庫開發人員的一句忠告。作為一個開發人員,無論使用何種型別的資料庫,都要遵守這個基本規則。

 

現實中,將資料庫作為Blackbox的開發人員是很多的。很多開發人員將資料庫就是作為一個資料留存的載體,透過標準化的SQL進行操作,不去對具體使用的資料庫進行了解。

 

這個問題的原因是很多的。其中一個重要原因就是在開發人員的觀念中,SQL語句都是通用標準的。只要輸入相同描述SQL,資料庫都能返回相同的結果。開發人員似乎不用去關注資料庫本身。

 

這種想法其實是錯誤的。目前我們使用最多的關係型資料庫系統,都是建立在關聯式資料庫模型的基礎之上。同時,行業中也有專門的SQL系列標準。流行的開源或者商用資料庫都宣稱支援標準SQL和關係模型。但是實際上,各個資料庫產品在實現標準的過程中是有所取捨、有所個性化的。

 

比如在Oracle中,一個重要的特性就是“查詢select不會被修改阻塞”,也就是任何時候都可以對資料表進行select,不在乎查詢資料是否正在被修改。這個特性大大提升了Oracle資料庫的併發能力。但是並不是每種RDBMS都是如此,如SQL Server或者SQLiteDBMS,就存在select被其他DML操作阻塞的情況。

 

另一個例子是關於鎖定範圍。如果要對一條記錄進行修改,Oracle資料庫只會對該資料行進行鎖定(行鎖機制)。而其他一些資料庫進行鎖定的範圍就會有差異。比如,SQL Server就是基於對頁page的鎖定,而另一些DBMS甚至會對錶級別進行鎖定。

 

對這些資料庫機制的瞭解,對我們進行開發的意義重大,可以幫助我們不犯根本性質的錯誤。比如,瞭解SQL Serverselect會被DML操作阻塞,就要意識到SQL Server環境下事務Transaction是要及時的提交。

 

 

另一部分的機制瞭解就是SQLSQL是一種描述性語言。同一個結果集合,使用不同的SQL描述,資料庫都會生成不同的執行計劃。不同的執行計劃方式,意味著不同的效率。所以,書寫一手“漂亮”的SQL是不容易的。需要開發人員瞭解最佳化器、SQL轉換機制和執行計劃。

 

 

所以,作為一個資料庫相關的開發人員不是一件容易的事情。會寫幾句SQL,用用預定義函式絕不是資料庫開發的全部。瞭解你的專案所使用的資料庫,知道自己在做什麼,是一個資料庫開發人員所具備的基本素質。

 

 

2、  Be Responsible To Your SQL

 

對於一個初學者,SQL是一種描述性語言。你需要什麼樣子的資料,不管什麼方法,只要能描述出來,理論上DBMS都可以返回正確的結果。但是,執行效率是有差異的。相同的結果集合,好SQL可能不到一秒鐘就可以返回結果,壞SQL可能幾個小時不能有結果。

 

我們經常在開發團隊遇到的場景是這樣的:開發人員書寫了一個SQL,測試入一個很小資料集合,可以返回正確的結果。就直接提交測試投產了。投產之後,隨著資料量的積累,原有SQL執行效能下降嚴重,最後很可能都執行不出結果。此時,開發團隊已經解散,修改原始碼的可能性很少,於是變成了DBA的噩夢。

 

這樣的場景,本質問題就出現在開發階段開發人員對SQL的責任缺失。開發人員應該對自己書寫的SQL負責,在保證結果正確的前提下,不斷最佳化SQL的書寫。這樣做的目的就是讓SQL在生產環境下也可以正確的執行。

 

做到SQL負責,聽起來是一個很抽象的概念。實際中,開發人員只需要從兩個方面入手:

 

首先,看看自己書寫SQL的執行計劃。檢視執行計劃,評估執行計劃不是DBA的專利。每個開發人員應該具有看懂SQL執行計劃,辨別常見Join的方式操作,識別好壞的能力。能看清SQL的缺點,才有改造的動力。

 

第二就是時刻注意自己的SQL在做什麼?聽起來這條規則很有問題,SQL幾種操作,我們都能夠書寫出來,難道還不知道自己的SQL在做什麼嗎?這裡筆者要強調的是資料操作範圍。修改一條記錄的SQL和修改一千萬條記錄的SQL書寫起來,形式可以是一樣的。但是,這樣的SQL執行時候的效果是天差地別。一次性修改一千萬記錄的SQL也許一瞬間就讓資料庫處在崩潰的邊緣。所以,一條SQL語句寫出來,開發人員一定要明白這個SQL處理的範疇是多大?一百條還是一百萬條?如果可能出現百萬條的可能,就一定要預先處理,設定一次操作的範圍上限。避免由於一次性的操作帶來的風險。

 

 

3、  Index or Not Index

 

 

這裡說說Index索引這個老話題。在Oracle環境下,最常見的索引是B+平衡樹索引。普通B樹索引具有幾個特徵:

 

ü        始終維持平衡狀態。從根節點到達所有葉子節點的距離相同;

ü        樹節點包括三類:一個根節點、若干分支節點和若干的葉子節點;

ü        葉子節點之間,透過雙向連結串列結構加以連線。可以方便的在葉子節點層進行導航;

ü        葉子節點上,儲存著索引列鍵值和對應的行rowid

ü        索引是一個單獨的段結構segment,一個enable的索引是和資料表索引列實時對應;

 

在開發SQL的執行計劃中,我們經常可以看到兩種路徑方式:Full Table ScanIndex Range Scan。這是資料表訪問的兩個代表性的方式。

 

ü        Full Table Scan(全表掃描):此種方式是對資料表資料的全部檢索。首先,Oracle會從物件的資料字典中,獲取到資料段頭塊的資訊(檔案號、塊號)。找到頭塊之後,從頭塊資訊中,獲取到該資料表所有相關extents的資訊和位置。之後依據extents的分配依次檢索資料塊。直到檢索到HWM(高水位線)下。FTS方式有個特點:堆表結構下,會檢索到所有分配給的資料塊(無論是否有資料內容)。所以,FTS操作的效率是隨著資料表的膨脹而變化的;

ü        Index Range Scan(索引範圍掃描):對資料表的檢索,並不直接入手資料表。而是從索引入手,透過讀少量的索引塊,獲取定位到符合條件的葉子節點rowid列表。之後,直接藉助rowid列表,就可以定位到符合條件的資料行。這種方式的特點是查詢效能不隨著資料表的脹大而發生變化。

 

 

通常情況下,索引路徑是我們追求的最佳化方向。在CBO時代,索引路徑因其少量的IO塊讀取成本通常小於FTS方式的。但是,並不是意味著所有SQL都會最佳化為索引路徑。索引是有成本的,新增索引是會給select帶來很多好處。但是,Oracle要維護資料索引列與索引樹的同步結構。這也就意味著索引會帶來DML操作的效能低下。所以,索引是一種有成本的最佳化手段,要統籌規劃。

 

本篇,我們介紹了三個開發人員需要注意的方面,下面繼續介紹其他一些開發原則。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-705517/,如需轉載,請註明出處,否則將追究法律責任。

相關文章