1. 程式人生 > >2.面向效能的設計與開發

2.面向效能的設計與開發

原文:https://docs.oracle.com/cd/B19306_01/server.102/b14211/design.htm#g34949

最佳系統性能始於設計,並貫穿系統的整個生命週期。在初始設計階段仔細考慮效能問題,在生產過程中更容易調整系統。
本章包含以下部分:
• Oracle方法論
• 瞭解投資選擇
• 瞭解可伸縮性
• 系統架構
• 應用設計原則
• 負載測試,建模和實現
• 部署新應用程式

2.1 Oracle方法論

隨著網際網路在商業應用中發揮更大作用,計算機系統變得越來越大,越來越複雜,系統性能變得越來越重要。為了適應這種情況,Oracle基於多年的設計和效能經驗制定了一套效能調優方法。該方法解釋瞭如何可以顯著提高系統性能,以及有哪些簡單明瞭的活動。

效能調優戰略的有效性各不相同,具有不同目的的系統 - 例如運營系統和決策支援系統 - 需要不同的效能調優技能。本書探討了任何資料庫設計人員,管理員或效能專家應該集中精力的注意事項。

效能問題通常是某些系統資源爭用或耗盡的結果。當系統資源耗盡時,系統無法擴充套件到更高的效能級別。本文的效能調優方法,基於對資料庫的仔細規劃和設計,以防止系統資源耗盡並導致停機。通過消除資源衝突,可以使系統可擴充套件到業務所需的級別。

2.2 瞭解投資選擇

隨著相對便宜,高效能處理器,記憶體和磁碟驅動器的出現,人們傾向於購買更多系統資源來提高效能。在許多情況下,新的CPU,記憶體或更多磁碟驅動器確實可以立即改善效能。但是,通過新增硬體實現的任何效能提升都應被視為對即時問題的短期緩解。如果應用程式的需求和負載率繼續增長,那麼您很可能在不久的將來面臨同樣的問題。

在其他情況下,額外的硬體根本不會提高系統的效能。設計不良的系統無論分配多少額外硬體都表現不佳。在購買其他硬體之前,請確保應用程式中沒有序列化或單執行緒。從長期來看,就每個業務事務使用的物理資源數量而言,提高應用程式的效率通常更有價值。

2.3 瞭解可伸縮性

可擴充套件性這個詞在開發環境中的許多上下文中使用。以下部分提供了針對應用程式設計人員和效能專家的可伸縮性說明。
本節包括以下主題:
• 什麼是可伸縮性?
• 系統可擴充套件性
• 影響可伸縮性的因素

2.3.1什麼是可伸縮性?

可伸縮性是系統處理更多工作負載的能力,系統資源使用量成比例增加。換句話說,在可伸縮系統中,如果您將工作負載加倍,那麼系統將使用兩倍的系統資源。這聽起來很明顯,但由於系統內部存在衝突,資源使用量可能會超過原始工作負載的兩倍。
由於資源衝突導致的可擴充套件性不佳的示例包括:
• 隨著使用者群增加,需要大量併發管理的應用程式
• 鎖活動增加
• 增加了資料一致性工作量
• 增加了作業系統的工作量
• 隨著資料量的增加,需要增加資料訪問的事務
• 糟糕的SQL和索引設計導致返回相同行數的邏輯I / O數量更多
• 降低可用性,因為資料庫物件需要更長的維護時間
如果應用程式將系統資源耗盡到在工作負載增加時無法實現吞吐量,則稱該應用程式是不可擴充套件的。這樣的應用導致吞吐量不可提升和較差的響應時間。
資源耗盡的示例包括以下內容:
• 硬體耗盡
• 大量事務處理時,表掃描導致不可避免的磁碟I / O短缺
• 網路請求過多,導致網路和排程瓶頸
• 記憶體分配導致分頁和交換
• 過多的程序和執行緒分配導致作業系統抖動
這意味著應用程式設計人員必須建立一個不管使用者群和資料量如何,使用的資源相同,並且不會將系統資源的負載超出其限制。

2.3.2系統可擴充套件性

可通過Internet訪問的應用程式具有更復雜的效能和可用性要求。有些應用程式的設計和編寫僅供Internet使用,但即使是典型的後臺應用程式(如總帳應用程式),也可能需要線上提供部分或全部資料。
網際網路時代應用的特徵包括以下內容:
• 一年365天,每天24小時的可用性
• 不可預測且不精確的併發使用者數
• 容量規劃困難
• 任何型別查詢的可用性
• 多層架構
• 無狀態中介軟體
• 快速開發
• 測試時間最小化
圖2-1顯示了經典的工作負載增長曲線,需求以不斷增長的速度增長。應用程式必須隨著工作負載的增加而擴充套件,並且還需要新增額外的硬體以支援不斷增長的需求。無論額外的硬體資源或重新設計工作如何,設計錯誤都可能導致實現達到極限。
圖2-1工作量增長曲線
“圖2-1工作量增長曲線”的描述
“圖2-1工作量增長曲線”的描述

應用程式受到非常短的開發時間框架的挑戰,測試和評估的時間有限。但是,糟糕的設計通常意味著在將來的某個時刻,系統需要重新設計或重新實施。如果在Internet上部署具有已知體系結構和實現限制的應用程式,並且如果工作負載超出預期需求,則將來確實存在失敗的可能性。從業務角度來看,糟糕的表現可能意味著客戶流失。如果Web使用者在七秒內沒有得到響應,那麼使用者的注意力可能會永遠丟失。
在許多情況下,遷移到重構系統的停機成本超過正確構建原始系統的成本。故事的寓意很簡單:從一開始就考慮到可擴充套件性的設計和實現。

2.3.3阻止可擴充套件性的因素

在構建應用程式時,設計人員和架構師應儘可能設計近完美的可擴充套件性。這有時被稱為線性可擴充套件性,其中系統吞吐量與CPU數量成正比。
在現實生活中,線性可擴充套件性是不可能的,因為存在超出設計師控制的因素。但是,應該使應用程式儘可能的擴充套件到可通過擴充套件硬體元件和新CPU技術來實現當前和未來的效能目標。
可能妨礙線性可擴充套件性的因素包括:
• 應用程式設計,實現和配置不佳
應用程式對可伸縮性的影響最大的因素有:
o 糟糕的架構設計可能導致昂貴的SQL無法擴充套件。
o 糟糕的事務設計可能導致鎖和序列化問題。
o 連線管理不良可能導致響應時間較長和系統不可靠。
但是,設計並不是唯一的問題。應用程式的物理實現也可能是薄弱環節,例如:
o 系統遷移到具有錯誤I / O策略的生產環境。
o 生產環境使用了與測試中生成的執行計劃不同的執行計劃。
o 給記憶體密集型應用程式分配大量記憶體,而不考慮在執行時釋放記憶體,由此可能會導致記憶體溢漏。
o 低效的記憶體使用和記憶體溢漏給操作虛擬記憶體子系統帶來了很大的壓力。這會影響效能和可用性。
• 硬體元件的大小調整不正確
隨著相對硬體價格的下降,硬體元件容量規劃變得越來越不成問題。但是,當系統的工作負載增加時,過多的容量會掩蓋可伸縮性問題。
• 軟體元件的侷限性
所有軟體元件都具有可伸縮性和資源使用限制。這適用於應用程式伺服器,資料庫伺服器和作業系統。應用程式設計不應對軟體提出超出其可處理範圍的要求。
• 硬體元件的限制
硬體不是完全可擴充套件的。大多數多處理器系統可以通過有限數量的CPU接近線性擴充套件,但是在某一點之後,每個額外的CPU雖然可以提高整體效能,但不是成比例的。可能有一段時間,額外的CPU不會提高效能,甚至會降低效能。此行為與工作負載和作業系統設定密切相關。
注意:
這些因素來自於Oracle Server Performance小組在調優不可擴充套件系統時的經驗。

2.4系統架構

系統架構有兩個主要部分:
• 硬體和軟體元件
• 根據需求配置正確的系統架構

2.4.1硬體和軟體元件

本節討論硬體和軟體元件。

2.4.1.1硬體元件

當今的設計師和架構師負責多層環境中每層的硬體規模和容量規劃。架構師的責任是平衡各種問題。這類似於橋樑設計師,他必須考慮橋樑的所有各種有效載荷和結構要求。橋樑的承載能力取決於最薄弱的部分。因此,橋樑設計要平衡所有元件同時達到其極限。
主要硬體元件包括:
• 中央處理器
• 記憶體
• I / O子系統
• 網路

2.4.1.1.1 CPU

可以有一個或多個CPU,它們的處理能力可以從手持裝置中的簡易CPU到高功率伺服器CPU。其他硬體元件的大小通常是基於多CPU的系統。請參見第9章“瞭解作業系統資源”。

2.4.1.1.2 記憶體

資料庫和應用程式伺服器需要大量記憶體來快取資料並避免耗時的磁碟訪問。請參見第7章“記憶體配置和使用”。

2.4.1.1.3 I / O子系統

I / O子系統包括客戶端PC上的硬碟,到高效能磁碟陣列之間。磁碟陣列每秒可以執行數千個I / O,並通過多個I / O路徑和熱插拔映象磁碟冗餘提供可用性。請參見第8章“I / O配置和設計”。

2.4.1.1.4網路

系統中的所有計算機都連線到網路,從調變解調器線路到高速LAN。網路規範的主要問題是頻寬(容量)和延遲(速度)。

2.4.1.2軟體元件

與具有通用硬體元件的方式相同,應用程式也具有通用功能元件。將軟體開發劃分為功能元件,可以更好地理解應用程式設計和體系結構。系統的某些元件可以通過購買現有軟體,以加速應用程式的實現,或避免重複開發通用元件。
軟體元件和硬體元件之間的區別在於,硬體元件僅執行一項任務,但一個軟體可以執行多種任務。例如,磁碟驅動器僅儲存和檢索資料,但客戶端程式可以管理使用者介面並執行業務邏輯。
大多數應用程式涉及以下元件:
• 管理使用者介面
• 實施業務邏輯
• 管理使用者請求和資源分配
• 管理資料和事務

2.4.1.2.1管理使用者介面

該元件對應用程式使用者最為明顯。這包括以下功能:
• 在使用者面前繪製螢幕
• 收集使用者資料並將其傳輸到業務邏輯
• 驗證資料輸入
• 控制應用程式的級別或狀態

2.4.1.2.2實現業務邏輯

該元件實現核心業務規則,是應用程式功能的核心。修該此元件中的錯誤可能非常昂貴。該元件同時使用宣告式和過程式兩種實現方法。宣告式活動的一個示例是定義唯一鍵和外來鍵。基於過程的邏輯的一個示例,如實施折扣策略。
該元件的通用功能包括:
• 將資料模型儲存到關係型表結構
• 在關係型表結構中定義約束
• 編寫程式邏輯以實現業務規則

2.4.1.2.3管理使用者請求和資源分配

所有軟體中都有該元件的實現。但是,有些請求和資源可能會受到應用程式設計的影響。
在多使用者應用程式中,使用者請求的大多數資源分配由資料庫伺服器或作業系統處理。但是,在使用者數量及其使用模式未知或快速增長的大型應用程式中,系統架構師必須主動確保沒有某個軟體元件過載或不穩定。
該元件的通用功能包括:
• 與資料庫的連線管理
• 有效執行SQL(遊標和SQL共享)
• 管理客戶端狀態資訊
• 平衡跨硬體資源的使用者請求負載
• 設定硬體/軟體元件的運維目標
• 持久化佇列以執行非同步任務

2.4.1.2.4管理資料和事務

該元件主要由資料庫伺服器和作業系統負責。
該元件的通用功能包括:
• 使用鎖和事務語義提供對資料的併發訪問
• 使用索引和記憶體快取提供對資料的優化訪問
• 確保在發生硬體故障時記錄資料更改
• 執行(為某資料定義的)規則

2.4.2根據需求配置正確的系統架構

配置初始系統架構很大程度上是一個迭代的過程。架構師必須在預算和進度限制內滿足系統要求。如果系統要求互動式使用者根據資料庫的內容處理業務決策,那麼使用者需求就會驅動架構。如果系統上的互動式使用者很少,那麼該體系結構是由流程驅動的。
互動式使用者應用程式示例:
• 會計和簿記應用程式
• 訂單輸入系統
• 電郵伺服器
• 基於Web的零售應用程式
• 交易系統
流程驅動的應用程式示例:
• 計費系統
• 欺詐檢測系統
• 直郵
在許多方面,流程驅動的應用程式比多使用者應用程式更容易設計,因為消除了使用者介面元素。但是,由於目標是面向流程的,因此不習慣處理大量資料和不同成功因素的架構師可能會感到困惑。流程驅動的應用程式來自基於使用者的應用程式和資料倉庫中使用的技能集。因此,本書側重於不斷髮展的互動式使用者系統架構。
注意:
建立系統架構不是一個確定性過程。它需要仔細考慮業務需求,技術選擇,現有基礎設施和系統,以及實際物理資源,如預算和人力。
以下問題可以激發對架構的思考,儘管它們不是系統架構的權威指南。這些問題演示了業務需求如何影響體系結構,實現的簡單化以及系統的整體效能和可用性。例如:
• 系統支援多少使用者?
大多數應用程式屬於以下類別之一:
o 使用頻率低或專用的系統,使用者很少
對於這種型別的應用程式,通常有一個使用者。應用程式設計的重點是通過提供良好的響應時間使單個使用者儘可能高效,同時使應用程式需要最少的運維。這些應用程式的使用者很少相互干擾,並且資源衝突最小。
o 企業共享應用程式,有中型到大型的使用者群
對於這種型別的應用程式,使用者數量受到公司中使用系統的員工數量的限制。因此,使用者數量是可預測的。但是,提供可靠的服務對業務至關重要。使用者將使用共享資源,因此設計必須解決在繁重的系統負載下的響應時間,每個會話使用的資源增長,以及未來增長的空間。
o Internet上的無限使用者群
對於此類應用,需要額外的工程以確保沒有系統元件超出其設計限制。這將產生瓶頸,使系統停止並變得不穩定。這些應用程式需要複雜的負載平衡,無狀態應用程式伺服器和高效的資料庫連線管理。此外,如果由於系統過載而無法滿足其請求,則應使用統計資訊和調控器來確保使用者獲得一些反饋。
• 什麼是使用者互動方法?
使用者介面的選擇範圍從簡單的Web瀏覽器到自定義客戶端程式。
• 使用者在哪裡?
使用者之間的距離會影響應用程式的設計方式,以應對網路延遲。該位置還會影響一天中的哪些時間繁忙,此時間段將無法執行批處理或系統維護功能。
• 什麼是網路速度?
網路速度會影響資料量,以及使用者介面與應用程式和資料庫伺服器的互動質量。高度互動的使用者介面需要在每個鍵擊或欄位級驗證時與後端伺服器通訊。較少互動的介面適用於頁面傳送和頁面接收模型。在慢速網路上,使用高度互動的使用者介面無法實現高資料輸入速度。
• 使用者可以訪問多少資料,以及有多少資料主要是隻讀的?
線上查詢的資料量會影響設計的所有方面,從表格和索引設計到表示層。設計工作必須確保使用者響應時間不隨資料庫大小而變。如果應用程式基本上是隻讀的,則複製和資料分發到應用程式伺服器中的本地快取成為可行的選擇。這也減少了資料庫的工作負載。
• 使用者響應時間需求是什麼?
考慮使用者型別很重要。如果使用者是位高層執行官,需要準確資訊做出快速決策,那麼使用者響應時間就不能妥協。其他型別的使用者(例如執行資料輸入活動的使用者)可能不需要如此高的效能水平。
• 使用者是否期望24小時服務?
這對於當今24小時交易的網際網路應用是強制性的。但是,在單個時區中執行的公司系統可能能夠容忍非工作時間的停機時間。此非工作時間停機時間可用於執行批處理或執行系統管理。在這種情況下,不執行完全可用的系統可能更經濟。
• 所有變更都必須實時進行嗎?
確定是否需要在使用者響應時間內完成事務,或者是否可以將它們排隊等待非同步執行非常重要。
以下是次要問題,這些問題也可能影響設計,但實際上對預算和實施的簡易性有更大的影響。例如:
• 資料庫有多大?
這會影響資料庫主機系統的大小。在具有非常大的資料庫的系統上,可能需要具有比工作負載所規定的更大的系統。這是因為大型資料庫的管理開銷很大程度上取決於資料庫大小。隨著表和索引的增長,需要更多的CPU在可接受的時間限制內完成表重組和索引構建。
• 業務交易所需的吞吐量是多少?
• 有哪些可用性要求?
• 是否存在構建和管理此應用程式的技能?
• 預算限制將迫使哪些妥協?

2.5應用設計原則

本節介紹構建應用程式時涉及的以下設計決策:
• 應用程式設計的簡單性
• 資料建模
• 表和索引設計
• 使用檢視
• SQL執行效率
• 應用程式實現
• 應用程式開發的趨勢
2.5.1應用程式設計的簡單性
應用程式與任何其他設計和工程產品沒有什麼不同。精心設計的結構,系統和工具通常可靠,易於使用和維護,並且概念簡單。從最一般的角度來看,如果設計看起來正確,那麼可能就是這樣。在構建應用程式時,應始終牢記這一原則。
考慮以下一些設計問題:
• 如果表設計過於複雜以至於沒有人能夠完全理解它,那麼該表可能設計得很差。
• 如果SQL語句太長且涉及到任何優化器都不可能實時有效地優化它,那麼可能存在不好的語句,事務或表設計。
• 如果表上有索引並且重複索引相同的列,那麼索引設計可能很差。
• 如果提交的查詢時,沒有適當措施來對線上使用者進行快速響應,那麼可能存在糟糕的使用者介面或事務設計。
• 如果對資料庫的呼叫從應用程式邏輯中抽象出來多層,那麼可能存在糟糕的軟體開發方法。

2.5.2資料建模

資料建模對於成功的關係型應用程式設計很重要。資料建模應該快速表達業務實踐。很可能會有關於正確資料模型的熱烈爭論。重要的是將最大的建模工作集中在最頻繁業務處理的實體上。在建模階段,很有可能花費太多時間來建模非核心資料元素,這導致開發時間的增加。使用建模工具可以快速生成模式定義,在需要快速原型時非常有用。

2.5.3表和索引設計

表設計在很大程度上是核心事務的靈活性和效能之間的折衷。為了使資料庫保持靈活性並能夠適應不可預見的工作負載,表格設計應該與資料模型非常相似,並且應該將其標準化為至少第3正規化。但是,使用者所需的某些核心事務可能需要非規範化以實現效能目的。
此技術的示例包括儲存預先連線的表,新增派生列和聚合值。Oracle通過叢集和物化檢視功能提供了許多用於儲存聚合和預加入資料的選項。這些功能允許最初採用更簡單的表格設計。
總之,應將重點和資源用於業務關鍵表,以便實現最佳效能。對於非關鍵表,可以採用設計中的快捷方式來實現更快速的應用程式開發。但是,如果原型設計和測試非核心表成為效能問題,則應立即應用補救設計工作。
索引設計也是一個迭代的過程,它是基於應用程式設計者生成的SQL。構建強制主鍵約束的索引和已知訪問模式的索引(例如人名)是明智的開始。通過改進應用程式和對實際資料量的測試來構建更好的索引,以便讓某些查詢的效能得到改進。在構建新索引時,應考慮以下因素:
• 將列加到索引或使用索引組織表
• 使用不同的索引型別
• 尋找索引成本
• 在索引中序列化
• 索引中對列排序

2.5.3.1將列加到索引或使用索引組織表

加速查詢的最簡單方法之一是通過消除執行計劃中的表訪問來減少邏輯I / O的數量。這可以通過將查詢引用的所有列附加到索引來完成。這些列是select列表列以及任何join或排序列。當耗時的I / O減少時,此技術對於加快線上應用程式響應時間特別有用。應該先用適當大小的資料測試應用程式。
更激進的方法是構建一個索引組織表(IOT)。但是,您必須小心確保IOT增加的葉子大小不會破壞減少I / O的努力。
2.5.3.2使用不同的索引型別
有幾種可用的索引型別,每種索引對某些情況有好處。以下列表提供了與每種索引型別相關的效能提示。

2.5.3.2.1 B樹索引

這些索引是標準索引型別,它非常適合主鍵和高選擇性(highly-selective,該列的資料值大多都不相同)的索引。作為複合索引,B樹索引可用於檢索由多索引列排序的資料。

2.5.3.2.2點陣圖索引

此類索引適用於資料值種類少的列(如性別)。通過壓縮技術,它們可以生成大量具有最小I / O的rowid。在多個非選擇性(non-selective,值基本相同)列上使用點陣圖索引,可以使用大量的rowid進行高效AND和OR操作,並且I / O最小。點陣圖索引在使用COUNT()的查詢中特別有效,因為查詢可以在索引中完成。

2.5.3.2.3 基於功能的索引

此類索引允許通過B樹訪問從使用基礎資料的函式派生的值。基於函式的索引在使用空值方面有一些限制,它們要求您啟用查詢優化器。
在查詢複合列以生成派生結果,或克服儲存在資料庫中的資料限制時,基於函式的索引特別有用。例如,查詢訂單中的訂單項超過從(銷售價格 - 折扣)x數量 派生的特定值,其中這些是表格中的列。另一個示例是將UPPER函式應用於不區分大小寫的搜尋。

2.5.3.2.4 分割槽索引

對全域性索引進行分割槽從而減少I / O. 定義好範圍或列表分割槽,定位某個索引分割槽,可以加速索引的掃描,減少查詢時間。

2.5.3.2.5 反向鍵索引

此類索引旨在消除插入程式上的索引熱點。這些索引非常適合插入效能,但它們的侷限性在於它們不能用於索引範圍掃描。

2.5.3.3 查詢索引成本

構建和維護索引結構可能很昂貴,並且可能消耗諸如磁碟空間,CPU和I / O容量之類的資源。設計師必須確保索引帶來的好處超過索引維護的負面影響。
索引維護成本簡單估算指南:每個帶索引的INSERT,DELETE或UPDATE所需要的資源,大約是對錶的DML操作所需要的資源的三倍。這意味著如果你INSERT進入一個有三個索引的表,那麼它將比INSERT沒有索引的錶慢大約10倍。對於DML,特別是對於INSERT重型應用程式,應該認真審查索引設計,這可能需要在查詢和INSERT效能之間進行折衷。
有關監視索引使用情況的資訊,請參見 Oracle資料庫管理員指南

2.5.3.4 在索引中序列化

使用序列或時間戳來生成自身索引的鍵值可能會導致資料庫熱點問題,從而影響響應時間和吞吐量。這通常是單調增長key導致右向增長索引(right-growing index)的結果。要避免此問題,請嘗試生成的鍵值插入在索引的全區間內,這會平衡索引,讓索引更具可擴充套件性和效率。您可以通過使用反向鍵索引或使用迴圈序列來設定字首和序列值來實現此目的。

2.5.3.5 對索引中的列進行排序

設計人員應該靈活地定義索引構建的規則。根據您的具體情況,使用以下兩種方法之一對索引中的鍵進行排序:
• 首先排序選擇性最多的列(也就是其值最不同的列)。此方法是最常用的方法,因為它提供了最快的訪問速度,並且對所需的實際rowid具有最小的I / O. 該技術主要用於主鍵和very selective的區間掃描。
• 通過對資料進行聚類或排序來對列進行排序以減少I / O. 在大區間掃描中,通常可以通過以最小選擇(the least selective)順序對列進行排序,或者以按照應該檢索的方式對資料進行排序的方式來減少I / O. 請參見第15章“使用索引和群集”。

2.5.4 使用檢視

檢視可以加速並簡化應用程式設計。簡單的檢視定義可以降低資料模型的複雜性,讓程式設計師的優先順序集中在檢索,顯示,收集和儲存資料。
但是,雖然檢視提供了乾淨的程式設計介面,但它們可能會導致 sub-optimal資源密集型查詢。最糟糕的檢視使用型別是檢視引用其他檢視並且它們在查詢中使用join的情況。在許多情況下,開發人員可以直接從表中查詢到結果而無需使用檢視。通常,由於其固有屬性,檢視使優化器難以生成最佳執行計劃。

2.5.5 SQL執行效率

在任何系統開發的設計和架構階段,都應該注意確保應用程式開發人員瞭解SQL執行效率。為此,開發環境必須支援以下特徵:
• 良好的資料庫連線管理
連線到資料庫是一項昂貴的操作,非常不可擴充套件。因此,應儘可能減少與資料庫的併發連線數。在應用程式初始化時就建立使用者連線是最理想的。但是,在基於Web或多層應用程式中,應用程式伺服器通常使用多路複用資料庫連線給使用者,上述實現會很困難。因此設計這些型別的應用程式時,應確保建立資料庫連線池,並且不要為每個使用者請求重新建立連線。
• 良好的游標使用和管理
最小化解析活動與維護使用者連線同樣重要。解析是解釋SQL語句併為其建立執行計劃的過程。此過程包含許多階段,包括語法檢查,安全檢查,執行計劃生成以及將共享結構載入到共享池中。有兩種型別的解析操作:
o 硬解析:第一次提交SQL語句,在共享池中找不到相同的SQL匹配。硬解析是資源最密集且不可擴充套件的,因為它執行解析中涉及的所有操作。
o 軟解析:第一次提交SQL語句,在共享池中發現相同的SQL匹配。匹配可能是其他使用者先前執行的結果。SQL語句是共享的,這有利於提高效能。但是,軟解析並不理想,因為它們仍然需要語法和安全檢查,這會消耗系統資源。
解析應儘可能地最小化,因此應用程式開發人員應設計為解析SQL語句一次,並執行多次。這是通過遊標完成的。經驗豐富的SQL程式設計師應該熟悉開啟和重新執行遊標的概念。
應用程式開發人員還必須確保在共享池中共享SQL語句。為此,請繫結變數以表示不同的查詢時更改的部分。如果不這樣做,則SQL語句可能會被解析之後永遠不會被其他使用者重用。要確保共享SQL,請使用繫結變數,不要將字串文字與SQL語句一起使用。例如:
字串文字的宣告:

SELECT * FROM員工 
  WHERE last_name LIKE'KING';

繫結變數的語句:

SELECT * FROM員工 
  WHERE last_name LIKE:1;

以下示例顯示了對簡單OLTP應用程式的測試結果:
測試 #支援的使用者數
不解析所有SQL語句 270
Soft解析所有SQL語句 150
硬解析所有SQL語句 60
每個事務處理的重新連線 30
這些測試是在四個CPU系統上進行的。隨著系統上CPU數量的增加,差異也會增加。有關優化SQL語句的資訊,請參見第11章“SQL調優概述”。

2.5.6應用程式實現

開發環境和程式語言的選擇在很大程度上取決於開發團隊的技能,以及架構決策。但是,有一些簡單的效能管理規則可以幫助實現可擴充套件的高效能應用程式。

  1. 選擇適合軟體元件的開發環境,不要讓它限制您關於效能決策的設計。如果是,那麼您可能選擇了錯誤的語言或環境。
    o 使用者介面
    程式設計模型可以是HTML或者直接呼叫視窗系統。開發方法應該關注使用者介面程式碼的響應時間。如果通過網路傳送HTML或Java,請嘗試最小化網路流量和互動。
    o 業務邏輯
    解釋型語言(例如Java和PL / SQL)是編寫業務邏輯的理想選擇。它們便攜,使邏輯變更相對容易。兩種語言在語法上都很豐富,易於閱讀和理解。如果業務邏輯需要複雜的數學函式,則可能需要編譯語言(如C)。業務邏輯程式碼可以位於客戶端,應用伺服器和資料庫伺服器上。但是,應用伺服器是業務邏輯最常見的位置。
    o 使用者請求和資源分配
    使用者請求和資源分配基本不受程式語言的影響,但封裝資料庫連線和遊標管理的工具和第4代語言可能會使用低效的機制。在評估這些工具和環境時,請檢查其資料庫連線模型及其對遊標和繫結變數的使用。
    o 資料管理和事務處理
    資料管理和事務處理基本不受程式語言的影響。
  2. 實現元件時,請實現其自己的功能,而不是與其他元件相關的功能。實現另一個元件的功能會導致次優設計和實現。這適用於所有元件。
  3. 不要留下功能缺陷,或在設計,實現或測試中使用還在驗證的元件。在許多情況下,缺陷在應用程式釋出之前,或在實際環境進行測試之前,不會被發現。這通常是架構不佳或初始系統規範的訊號。在初始系統設計,構建和實施過程中,資料歸檔/清除模組最常被忽略。
  4. 在實現過程邏輯時,使用過程語言,例如C,Java或PL / SQL。在實現資料訪問(查詢)或資料更改(DML)時,請使用SQL。此規則特定於業務邏輯模組程式碼,其中過程程式碼與資料訪問(非過程SQL)程式碼混合使用。雖然將過程邏輯放入SQL訪問中有很大的誘惑力,但這往往會導致資源密集SQL的效能不佳。帶有DECODE case語句的SQL語句,以及具有大量OR或帶有UNION和MINUS的set運算子的SQL語句,通常都需要優化。
  5. 儘量訪問快取,避免更改重複檢索的資料。但是,要確保快取機制易於使用,並確保它確實比用原始方法訪問資料便宜。這適用於應在本地快取或儲存常用資料值的所有模組,而不是從遠端或昂貴的資料儲存中重複檢索。
    本地快取最常見的使用場景包括:
    o 當天的日期。SELECT SYSDATE FROM DUAL可以佔資料庫工作量的60%以上。
    o 當前使用者名稱。
    o 重複的應用程式變數和常量,例如稅率,折扣率或位置資訊。
    o 本地快取資料可以進一步擴充套件到在應用伺服器中間層中構建本地資料快取。這有助於減輕中央資料庫伺服器的負擔。但是,在構建本地快取時應小心謹慎,避免它們不會變得過於複雜,以至於不能提供效能提升。
    o 本地序列生成(local sequence generation)。
    應考慮如何設計快取的更新。例如,如果使用者在午夜登入,而前一日的日期被快取的話,則使用者的日期值將變為無效。
  6. 優化元件之間的介面,並確保在最可擴充套件的配置中使用所有元件。此規則需要易於理解,並適用於所有模組及其介面。
  7. 使用外來鍵引用。通過應用程式實現引用完整性是昂貴的。您可以通過從父表中select子表的列值並確保它的存在來維護外來鍵引用。Oracle提供的外來鍵約束實施(不使用SQL)快速,易於宣告,並且不會有網路流量。
  8. 考慮在應用程式中設定操作和模組名稱,這些名稱可以用在端到端應用程式跟蹤中。這樣可以更靈活地跟蹤工作負載問題。請參閱“端到端應用程式跟蹤”。

2.5.7 應用程式開發趨勢

當今應用程式開發面臨的兩大挑戰是,越來越多地使用Java來替換C或C++等編譯語言,並且增加了面向物件技術的使用,從而影響了架構設計。
Java為程式設計師提供了更好的程式碼可移植性和可用性。但是,Java存在許多與效能相關的問題。由於Java是一種解釋型語言,因此執行相同邏輯的速度比C等編譯語言慢。因此,客戶端系統的資源使用量會增加。這需要在客戶端或中間層系統中應用更強大的CPU,並且程式設計師需要更加謹慎地編寫有效程式碼。
由於Java是面向物件的語言,因此它鼓勵將資料訪問絕緣到不執行業務邏輯的類中。結果,程式設計師可能在不知道所使用的資料訪問效率的情況下呼叫某個方法。這往往導致資料庫訪問非常小,並使用最簡單粗暴的資料庫介面。
使用這種型別的軟體設計,查詢並不總是帶有效的WHERE語句,並且行過濾在Java程式中執行。這是非常低效的。此外,對於DML操作 - 特別是對於資料插入,執行多次單個INSERT,不可能使用Array介面。在某些情況下,過程呼叫會使效率降低。與實際資料庫呼叫相比,將資料移入和移出資料庫使用更多資源。
通常,最好將資料訪問呼叫放在業務邏輯的旁邊,以實現最佳的整體事務設計。
在程式設計級別接受面向物件已導致在Oracle Server中建立面向物件的資料庫。這在許多方面表現出來,從在BLOBs中儲存物件結構並且僅將資料庫有效地用作indexed card檔案到使用Oracle物件關係特徵。
如果採用面向物件的方法進行模式設計,那麼請確保不會失去關係儲存模型的靈活性。在許多情況下,面向物件的模式設計方法最終導致嚴重非規範化的資料結構,需要大量的維護和與物件相關的REF指標。通常,這些設計是用關係儲存方法取代的分層和網路資料庫設計的某種倒退。
總之,如果您將資料長期儲存在資料庫中並預期在同一模式上進行特定查詢或應用程式開發,那麼您可能會發現關係型儲存方法提供了最佳效能和靈活性。

2.6 負載測試,建模和實現

本節介紹工作負載估計,建模,實現和測試。本節包括以下主題:
• 資料sizing
• 估算負載
• 應用程式建模
• 測試,除錯和驗證設計

2.6.1 資料sizing

如果使用較差的樣本集,在處理可變長度資料時,您可能會遇到sizing估計值的錯誤。隨著資料量的增長,您的鍵長度可能會大幅增長,從而改變您對列大小的假設。
當系統執行時,預測資料庫增長變得更加困難,特別是索引。表隨著時間的推移而增長,並且索引在鍵生成,插入模式和行刪除方面受到應用程式個別行為的影響。最糟糕的情況是使用升序鍵插入,然後從左側刪除大多數行但不刪除所有行。這留下了空隙和浪費的空間。如果你有這樣的索引使用,請確保你知道如何使用線上索引重建工具。
DBA應監視每個物件的空間分配,並查詢可能增長失控的物件。對應用程式的良好理解可以突出快速或不可預測地增長的物件。這是任何系統的效能和可用性規劃的關鍵部分。在實現生產資料庫時,設計應嘗試確保在互動式使用者使用應用程式時進行最小的空間管理。這適用於所有資料,臨時和回滾段。

2.6.2 估算負載

用於容量規劃和測試目的的負載估算通常被描述為黑色藝術。在考慮所涉及的變數數量時,很容易理解為什麼這個過程在很大程度上不可能精確正確。但是,設計人員需要為系統指定CPU,記憶體和磁碟驅動器,並最終釋出應用程式。有許多技術用於確定sizing,每種技術都有其優點。sizing時,最好使用以下兩種方法來驗證您的決策過程並提供支援文件:
• 從類似系統推斷
• 基準

2.6.2.1 從類似系統推斷

這是一種完全靠經驗的方法,具有相似特徵和已知效能的現有系統被用作基礎系統。然後,估算專家根據已知的差異修改規格。這種方法的優點在於它與現有系統相關,但在處理差異時幾乎沒有提供幫助。
在準備工程專案的成本時,這種方法幾乎用於所有大型工程學科(例如大型建築物,船舶,橋樑或石油鑽井平臺)。如果參考系統的大小與預期系統的大小不同,則某些元件可能已超出其設計限制。

2.6.2.2 基準測試(Benchmarking)

基準測試過程既耗費資源又耗時,並且可能無法產生正確的結果。通過在早期開發或原型中模擬應用程式,存在測量與實際生產系統無關的危險。這聽起來很奇怪,但在多年來使用資料庫開發組織對客戶應用程式進行基準測試時,Oracle尚未看到基準應用程式與實際生產系統之間的可靠關聯。這主要是由於開發過程中引入了效率低下的應用程式。
但是,基準測試已成功用於將系統估算到可接受的精確範圍。特別是,基準測試非常擅長確定系統滿載時的實際I / O要求和測試恢復過程。
基準是所有系統元件的極限。由於所有元件都受到壓力,因此在基準測試時能看到應用程式設計和實現中的所有錯誤。基準測試還測試資料庫,作業系統和硬體元件。由於大多數基準測試都是匆忙執行的,因此在系統元件發生故障時會出現缺陷和問題。基準測試是一項壓力很大的活動,需要相當多的經驗才能充分利用基準測試。

2.6.3應用程式建模

應用程式建模的範圍可以從複雜的數學建模到簡單計算。這兩種方法都有其優點,一種方法試圖非常精確,另一種方法估計總量。這兩種方法的缺點是它們不允許實現錯誤和低效率。
估算和sizing過程是不精確的。但是,通過調查過程,可以得到一些智慧估算。整個估算過程不允許因不良SQL,索引設計或遊標管理引入的應用程式效率低下。sizing工程師應該為應用程式效率低下預留一些資源。效能工程師應該發現效率低下並使估算看起來很現實。Oracle效能方法中描述了發現應用程式低效的過程。

2.6.4測試,除錯和驗證設計

測試過程主要包括功能和穩定性測試。在該過程的某個階段,執行效能測試。
以下列表描述了一些用於應用程式效能測試的簡單規則。如果記錄正確,這將為應用程式上線後的生產應用程式和容量規劃過程提供重要資訊。
• 使用 Automatic Database Diagnostic Monitor (ADDM)和SQL Tuning Advisor進行設計驗證
• 使用實際資料量和分佈進行測試
所有測試必須使用完全填充的表完成。測試資料庫應包含代表生產系統的資料,包括表之間的資料量和關係。應構建所有生產索引,並正確填充模式統計資訊。
• 使用正確的優化器模式
應使用將在生產中使用的優化器模式執行所有測試。Oracle的所有研發工作都集中在查詢優化器上,因此建議使用查詢優化器。
• 測試單個使用者的效能
應對空閒或輕度使用的系統上的單個使用者進行可接受效能測試。如果單個使用者在理想條件下無法達到可接受的效能,則在共享資源的多個使用者下不可能有可接受的效能。
• 獲取並記錄所有SQL語句的計劃
獲取每個SQL語句的執行計劃,並且應該至少執行一次語句獲取一些度量標準。此過程應用於驗證優化程式是否已獲取最佳執行計劃,並且可以根據CPU時間和物理I / O來理解SQL語句的相對成本。此過程有助於識別將來需要進行大量調整和效能工作的事務。有關計劃穩定性的資訊,請參見第18章“使用計劃穩定性”。
• 嘗試多使用者測試
此過程難以準確執行,因為使用者的工作負載可能無法完全量化。但是,應測試執行DML語句的事務以確保不存在鎖衝突或序列化問題。
• 使用正確的硬體配置進行測試
使用盡可能靠近生產系統的配置進行測試非常重要。這對於網路延遲,I / O子系統頻寬以及處理器型別和速度尤其重要。如果不這樣做,可能會導致對潛在效能問題的錯誤分析。
• 測量穩態效能
在進行基準測試時,在穩態條件下測量效能非常重要。每個基準測試執行應該有一個預熱階段,使用者連線到應用程式並逐漸開始執行應用程式的工作。此過程允許將頻繁快取的資料初始化到快取中,並且單個執行操作(例如解析)在穩態條件之前完成。同樣,在基準測試執行結束時,應該有一個減速期,資源從系統中釋放出來,使用者停止工作和斷開連線。

2.7 部署新應用程式

本節介紹了部署應用程式時涉及的以下設計決策:
• 釋出策略
• 效能檢查表

2.7.1 釋出策略

當推出新的應用程式時,通常採用兩種策略:
• Big Bang方法 - 所有使用者立即遷移到新系統
• Trickle方法 - 使用者從現有系統緩慢遷移到新系統
這兩種方法都有優點和缺點。Big Bang方法依賴於在所需規模下對應用程式的可靠測試,但具有資料轉換最小化和與舊系統同步的優勢,只需關閉舊系統。Trickle方法允許在負載增加時除錯可伸縮性問題,但在遷移階段,可能需要將資料遷移到遺留系統和從遺留系統遷移出。
很難推薦採用哪一種方法,因為每種方法都存在相關風險,可能會在轉換髮生時導致系統中斷。當然,Trickle方法允許在引入新應用程式時對真實使用者進行分析,並允許重新配置系統,同時僅影響遷移的使用者。這種方法會影響早期採用者的工作,但會限制支援服務的負擔。這意味著計劃外中斷僅影響一小部分使用者。
關於如何釋出新應用程式是根據不同的業務來決定的。採用的方法將有其獨特的外部壓力和內部壓力。從測試中獲得的資訊越多,您就越能情況哪種方法最適合。

2.7.2 效能檢查表

為了協助釋出過程,構建一個任務列表 - 如果正確執行 - 將增加生產中最佳效能的可能性 - 如果存在問題,則啟用應用程式的快速除錯:

  1. 當您建立生產資料庫的控制檔案時,為MAXINSTANCES,MAXDATAFILES,MAXLOGFILES,MAXLOGMEMBERS,和MAXLOGHISTORY設定比預期更高的值。這會導致更多的磁碟空間使用和更大的控制檔案,但如果在緊急情況下需要擴充套件,則可以節省時間。
  2. 將塊大小設定為用於開發應用程式的值。如果在與實際相當的資料量上執行測試並且SQL執行正確,則將schema統計資訊從開發/測試環境匯出到生產資料庫。
  3. 設定最小數量的初始化引數。理想情況下,大多數其他引數應保留為預設值。如果要執行更多調優,則應在系統出現效能問題時考慮。有關初始例項配置中引數設定的資訊,請參見第4章“為效能配置資料庫”。
  4. 通過設定資料庫物件的儲存選項來管理塊爭用。如果INSERT/ UPDATE/ DELETE使用頻繁,應用自動段空間管理建立表和索引。為避免回滾段的爭用,應使用自動撤消(undo)管理。有關撤消和臨時段的資訊,請參見第4章“為效能配置資料庫”。
  5. 應驗證所有SQL語句是否最優並瞭解其資源使用情況。
  6. 驗證連線到資料庫的中介軟體和程式在連線管理中是否有效,並且不會重複登入/登出。
  7. 驗證SQL語句是否有效地使用遊標。每個SQL語句應解析一次,然後執行多次。沒有達到這種效果最常見的原因是,沒有使用繫結變數,而是在WHERE子句裡使用了字串文字。如果使用預編譯器來開發應用程式,那麼確保引數MAXOPENCURSORS,HOLD_CURSOR以及RELEASE_CURSOR已經從之前的預設值重置為預編譯應用程式。
  8. 驗證所有模式物件是否已從開發環境正確遷移到生產資料庫。這包括表,索引,序列,觸發器,包,過程,函式,Java物件,synonyms,grants和檢視。確保在測試環境做的任何修改都反應到生產環境。
  9. 系統釋出後,立即建立一組統計資訊基線,該統計資訊包括來自與資料庫與作業系統。這是第一組統計資訊,可以驗證和糾正在設計和部署過程所做的任何假設。
  10. 開始預測第一個瓶頸(總會有一個瓶頸)並遵循Oracle效能方法來提高效能。有關詳細資訊,請參閱第3章“效能改進方法”。