從使用者角度來說,軟體性能就是軟體對使用者操作的回應時間。更明確的說,當使用者按下一個按鈕、發出一條指令或在 web 頁面上按下一個連結,從使用者點選開始到應用系統以使用者能察覺的方式把操作的結果展示出來,這個過程所消耗的時間就是使用者對軟體性能的直觀印象。
對於用戶回應時間,有一個普遍的標準 2/5/10 秒原則:在 2 秒之內給客戶回應被使用者認為是「非常有吸引力」的用戶體驗。在 5 秒之內回應客戶被認為是「比較不錯」的用戶體驗。在 10 秒內給用戶回應被認為是「糟糕」的用戶體驗。行動裝置更是超過 3 秒,就有 53% 的使用者會直接放棄。
我們還要考慮「使用頻率」的概念。電腦在最一開始安裝 Windows 系統可能要 1 個小時,我們為什麼覺得這很正常呢?因為我們很久才安裝一次系統,如果系統使用得當,可能一個系統用幾年都不用重裝。但假如我們在系統上安裝任何小軟體所需時間都這麼長,那我們一定是無法忍受的。
減少系統回應時間,改善使用者的體驗,提高用戶滿意度
對 HCP 來說也就是如何讓 Oracle 的程式跑的更快。DB Tuning 顯然是一個很大的問題,但不外乎從以下幾個方面進行:
SQL 語法優化
根據語句和資料庫索引的情況,結合查詢計畫的分析結果,重寫性能較低的查詢語句,在執行查詢前執行表分析語句等。
資料結構優化
包含根據實際的應用中業務邏輯,對資料庫的結構進行重新設計,或創建相關索引裡提高查詢效率。
儲存結構優化
在資料量較大的情況下,可以考慮通過資料庫的存儲結構進行優化,比如對資料進行 partition ,將資料存儲在磁碟陣列伺服器上等。
資料庫設置優化
調整資料庫和資料結構的相關參數,提高應用訪問系統的效率。
我的做法:最小化 PIO 與 LIO
這些方面大家應該都有所瞭解,我也不再贅述。在此和大家分享一些我的心得:我認為 DB Tuning 的目標是以最小的資料庫訪問次數提取更多地資料行來生成最佳的執行計畫(盡可能最小化物理讀(PIO)與邏輯讀(LIO))。儘量減少使用 loop,Oracle 支持 Procedural Language/SQL。像其他語言一樣,支持控制結構、支持循環結構,便於寫複雜的邏輯。與此同時 loop、end loop 就大量的出現在代碼中,必然會導致不斷的與 DB 進行交互、不斷進行 I/O,這與 DB Tuning 目標是完全背道而馳的。
舉例來說:需要從 table1 撈取中的 1000 筆資料,可以這樣:
for variable in 1 . . 1000
loop
select * from table1 where key= variable;
end loop;
// 或者:
select * from table1 where key <=1000
很明顯使用 Loop 會有 1000 次與 DB 交互,反之則只有一次,效能相差不言而喻。
但是實際開發的過程中,有很多的複雜的邏輯,我們也不可能不用循環結構。其實也有很多的方法可以處理,最終的目標就是盡可能最小化 PIO 與邏 LIO。例如 Cursor 可以使用 Fetch bulk collect Into 減少 fetch 的次數(以空間換取時間),使用 Oracle Temporary Table 把一些需要使用的資料先撈出來暫存,之後從 Temporary Table 撈取,不用一次一次的從基表中撈取等。
愚公移山與 DB Tuning
最後再以一個神話故事「愚公移山」來說明 DB Tuning 目標:以最小的資料庫訪問次數提取更多地資料行來生成最佳的執行計畫。
- 以最小的資料庫訪問次數
愚公:無數次
神仙:一次 - 提取更多地資料行
愚公:一次一筐
神仙:一次一座山 - 最佳的執行計畫
有比神仙搬走山更好的移山計畫嗎?