在大(dà)多數情況下,一套應用系統的效率問(wèn)題在表象上都(dōu)指向了I/O問(wèn)題。I/O效率低下的确是可(kě)能的原因之一,但(dàn)除了存儲設備在硬件(jiàn)、操作(zuò)系統方面的約束原因之外,應用系統數據庫設計(jì)及數據庫操作(zuò)的SQL語句也可(kě)能是産生(shēng)I/O瓶頸問(wèn)題的根本性原因。試想如(rú)果我們想從(cóng)北京到天津,但(dàn)我們偏偏要從(cóng)鄭州繞一圈過去(qù),這時候開什麽車已經不重要了,因爲這時路(lù)遠(yuǎn)是主要矛盾。
因此,在應用系統開發之初,SQL程序員(yuán)除了要了解業務需求以外,還(hái)必須關注應用中SQL的效率可(kě)用性。SQL的效率可(kě)用性在開發中往往可(kě)以反映爲如(rú)下幾個技術(shù)層面的運用:
❑恰當的數據庫連接機(jī)制。
❑高效的遊标使用和管理(lǐ)。
❑SQL執行中的硬解析、軟解析。
❑無論哪種解析,其計(jì)劃是優化的。
如(rú)下圖所示:
Oracle中的客戶連接和SQL執行
Oracle客戶連接是以進程方式體(tǐ)現在操作(zuò)系統中的,而在Oracle中則表現爲一個個的服務器進程。每個服務器進程都(dōu)有其獨立的堆棧結構、會話(huà)數據信息、遊标信息、數據排序區域。不僅如(rú)此,所有的服務器進程會共享Oracle SGA,在SQL執行過程中,所有的SQL會在SGA中的Library Cache(庫緩存)内存結構中被緩存,同時被緩存的還(hái)有該SQL對應的可(kě)執行僞代碼(Executing Plan:具體(tǐ)的執行計(jì)劃)。
客戶連接本身(shēn)就(jiù)是一個資源消耗型工(gōng)作(zuò),從(cóng)應用開發的角度來(lái)講,數據庫同時連接的用戶數應盡可(kě)能地少,這樣才會降低服務器的壓力。同時,對于某
個具體(tǐ)的用戶連接進程來(lái)說(shuō),其數據庫連接最好在應用啓動時完成,而不是在應用進行中不斷地連接、斷開、再連接。推而廣之,在一套多層結構的應用裡(lǐ),中間件(jiàn)層(應用服務器層)提供的“數據庫連接池”(connection pool功能)就(jiù)是用于實現這個目的的,它可(kě)保證不會出現頻繁的數據庫連接及斷開操作(zuò)。
所以,中間件(jiàn)服務器的數據庫連接緩存池可(kě)以起到連接緩沖的作(zuò)用,這是一種在互聯網下避免數據庫連接沖擊載荷的重要技術(shù)手段。
站(zhàn)在SQL的角度,最大(dà)限度地減少SQL執行過程中的語法分(fēn)析活動,是SQL優化的一個準則。我們知道,在Oracle執行SQL語句時,語法分(fēn)析是解釋并執行SQL語句的首要過程,包括分(fēn)析SQL句法、檢查執行權限、生(shēng)成執行計(jì)劃、裝載共享結構等。語法分(fēn)析結束後,數據庫優化器将确定其執行計(jì)劃,并将其編譯成僞代碼後提交Oracle内核執行。語法分(fēn)析有兩種不同類型的分(fēn)析方式和操作(zuò)步驟:硬解析和軟解析。
如(rú)果數據庫内核系統發現一個SQL語句是首次被提交,沒有在共享池中找到該SQL的執行痕迹,則數據庫不得(de)不對這條語句執行硬解析,包括SQL語法分(fēn)析、确定執行計(jì)劃、編譯執行等過程。這種解析方式必然會造成對資源的大(dà)量使用。
軟解析與硬解析不同。如(rú)果一個SQL語句被提交給數據庫,而這條語句(SQL及其對應的SQL執行計(jì)劃Execution Plan)可(kě)以在一個稱爲庫緩存(Library Cache)的共享池中找到,那這條SQL語句可(kě)能就(jiù)不必再次硬解析了,原因是不久以前(若幹時間内,可(kě)能是幾分(fēn)鍾或幾小時内)某個用戶曾經執行過這條SQL語句。如(rú)果這條SQL語句已被緩存到庫緩存中(共享),其語法分(fēn)析和編譯結果可(kě)以被後續的用戶所使用,從(cóng)而避免再次被解析。
顯然,這有益于降低系統資源的使用,提高整體(tǐ)性能。有一點需要說(shuō)明,雖然這種情況下的硬解析過程省略了,但(dàn)SQL的句法分(fēn)析和用戶執行權限檢查仍然存在,因此,軟解析仍然會部分(fēn)消耗系統資源。這是SQL執行的必然代價。
從(cóng)性能上看(kàn),一條SQL在經曆硬解析後,如(rú)果再次被執行,則執行應爲軟解析方式。這就(jiù)要求SQL在編程中具有一緻性。因此,在設計(jì)過程中最好能夠制定某種編程規範。我曾在北京的一家著名數據處理(lǐ)公司看(kàn)到過其内部編制的SQL規範,摘取其中幾條供大(dà)家參考,如(rú)下所示:
對于表名的使用
規則一:必須大(dà)寫
規則二:多表連接查詢,表名按升序自(zì)然排列,不能含有多餘的空格
規則三:優先使用預定義視圖,而非在線視圖(inline view)或子查詢
規則四:使用在線視圖(inline view)或子查詢時,請(qǐng)先行提交需求
……
對于列名的使用
規則一:必須小寫
規則二:列的出現順序嚴格按照(zhào)其在表中的位置按順序出現,不能含有多餘空格
……
SQL語句所使用的變量
規則一:使用綁定變量
規則二:變量的數據類型定義需采用%type
……
SQL模塊化的要求
規則一:基礎模塊建議(yì)在存儲過程、函數中完成
規則二:基礎模塊群建議(yì)在包中完成
SQL語句的注釋說(shuō)明
……
在這些規範中,可(kě)看(kàn)到有關規範化的兩個舉措:
❑SQL的規範化編寫
❑SQL的可(kě)重用性側重
程序員(yuán)可(kě)通過編寫盡量标準且通用的SQL語句,來(lái)适應這種硬解析及軟解析執行機(jī)制,避免系統中出現大(dà)量“陌生(shēng)”的SQL語句,進而減少對CPU資源的申請(qǐng)(次數和時間),這不也是優化的一部分(fēn)嗎(ma)?
爲了保證絕大(dà)多數SQL語句可(kě)以在共享池中共享,程序代碼中的SQL應盡可(kě)能使用綁定變量,這樣可(kě)以避免SQL在執行中因變量的不同,而導緻數據庫優化器對SQL語義曲解,進而導緻硬解析出現。
當然,綁定變量的使用也是典型的雙刃劍,但(dàn)大(dà)多數情況下其效果是好的。不過有一點要提醒的是,在程序設計(jì)階段就(jiù)進行約定非常重要。SQL編程規範要争取在設計(jì)階段完成。
本站(zhàn)文章(zhāng)爲深圳網站(zhàn)建設·源美網絡原創策劃,如(rú)有版權糾紛或者違規問(wèn)題,請(qǐng)聯系我們删除,謝謝!
上一篇: 數據庫視圖的使用評估
售後保障
承諾任何問(wèn)題1小時内解決數據備份
更安全、更高效、更穩定價格公道精準
項目經理(lǐ)精準報價不弄虛作(zuò)假合作(zuò)無風(fēng)險
重合同講信譽,無效全額退款