l 日誌表應該以時間作分區,方便清理html
通常應用都會有一些表用來記錄用戶操做日誌,數據變動記錄,交易流水等日誌型的庫表。這些表最好按時間字段作分區,這樣在遷移或者清理歷史記錄時會比較方便,藉助oracle的分區交換清理特性,效率比delete高不少。程序員
l 頻繁訪問的sequece應該增長cache算法
Oracle在建立序列能夠指定cache參數,若是打開這個參數,Oracle就能夠預先生成一些sequece,這樣應用獲取sequece相互爭用數據塊的機率就會減小,加快獲取sequece速度。sql
l 隊列表也應該作分區,減小出現高水位問題數據庫
有時咱們會使用數據庫表存放待處理的信息,處理完後把記錄刪除,像是消息隊列同樣。這種咱們稱之爲隊列表。這種表常常會出現高水位的問題,即某一瞬間忽然涌入了不少數據,等系統把表裏面記錄處理完,刪除後整個表訪問速度仍是很慢(由於高水位被上移後沒恢復)。這時若是庫表有分區,則不容易出現這種問題。編程
l 減小外鍵使用api
在設計庫表時咱們通常要使用外鍵以輔助表示不一樣庫表數據的關聯,但在實際部署時最好不要把外鍵加上。一個緣由是外鍵會影響數據插入刪除效率,更重要的緣由是加了外鍵的庫表在數據清理,修復時會帶來許多麻煩。性能優化
l 減小存儲過程服務器
有些程序員喜歡使用存儲過程封裝業務邏輯,雖然這樣處理數據速度快,但把壓力都留給了數據庫服務器。而數據庫服務器資源每每是比較有限的,並且比較難擴展。而應用服務器資源相對會豐富一些,也好擴展。因此建議儘可能少使用存儲過程,即便用也不要放太多業務邏輯。併發
l 使用綁定變量
儘量使用綁定變量代替拼sql,這樣一是減小sql注入風險,另一個是讓數據庫能夠複用執行計劃(sql文本相同的纔有可能複用),減小數據庫生成執行計劃的消耗。
l 使用並行
Oracle提供並行技術,能夠把一個sql涉及的數據集拆分紅多份,交由不一樣進程處理,以加快數據處理速度。對於OLAP系統,能夠考慮使用此技巧提升sql運行速度。
l 使用hint避免數據量變化過大的表
有時候咱們的應用會出現一些數據變化比較大的表,有時表裏面只有幾十條數據,有時可能有幾萬,幾十萬條。對於這種表的訪問最好使用hint強制數據庫在任何狀況都使用索引訪問,由於在數據量小時數據庫生成的執行計劃多是使用全表掃描,到後面數據發生變化時因爲sql沒有變,執行計劃也沒變,這時使用全表掃描效率就會很低。
l 使用tt 共享內存等
當一個會話須要訪問一個數據塊,而這個數據塊正在被另外一個用戶從磁盤讀取到內存中或者這個數據塊正在被另外一個會話修改時,當前的會話就須要等待,就會產生一個buffer busy waits等待,也伴隨着Latch爭用。若是太多的會話去訪問相同的數據塊致使長時間的buffer busy waits等待,一般表現形式爲CPU使用率很高,但吞吐量很低。形成熱快的緣由多是數據庫設置致使或者重複執行的SQL 頻繁訪問一些相同的數據塊致使。
l 兩個大表關聯查詢儘可能走hash join
雖然oracle提供了不少種表關聯算法,可是通過實驗,對兩個數據量大的錶鏈接仍是使用hash鏈接效率最高。
l 儘可能少用業務要素做爲主鍵
不使用業務要素做爲主鍵,能夠爲系統提供不少便利性。一是避免需求變動,原來。二是
l 合理使用縱表和橫表設計
所謂橫表就是指把一個實體的全部特性存儲在一行記錄,造成(ID,屬性1,屬性2,。。。,屬性N)的庫表。
而縱表則是把實體屬性分開多條記錄存儲,設計成(ID,屬性名稱,屬性值)這樣的庫表。
下面是一個橫表和縱表的例子:
使用橫表好處:
1 比較直觀,查詢比較方便
2 屬性值能夠根據屬性內容設計,例如年齡用number類型存儲,職業用varchar2存儲
使用縱表好處:
1 避免單表字段不停擴展,oracle是行存儲數據庫,記錄字段越多,記錄掃描時消耗的IO就會更多
2 增長屬性比較方便
建議:對於頻繁使用的屬性放橫表,對於不頻繁使用的屬性(例如住址),或者只有少部分記錄有的屬性(例如博客)放縱表。
l 頻繁使用的小表能夠考慮設置cache參數
設置了cache後,oracle會盡可能讓這個表的數據保持在內存,提升訪問速度。我碰到過把操做員和菜單信息表加了cache參數,大幅提升登陸速度的狀況。
l 物化視圖
普通視圖只是用於簡化複雜查詢,對於效率提高不大。Oracle提供了一種叫物化視圖的特殊對象,能夠把視圖查詢的結果集存起來,而且支持在基礎數據變化時自動刷新。不過物化視圖bug多,使用須要謹慎。
l 使用rac集羣的數據庫,最好分業務使用不一樣優先節點
因爲oracle訪問數據塊時要求先把數據裝載到內存,若是有某個數據塊頻繁被不一樣實例節點訪問,會致使rac集羣頻繁地把數據從一個節點機器傳輸到另外一個節點,這樣會很消耗時間。因此建議不一樣業務優先訪問不一樣rac節點,這樣能夠減小數據爭搶的機率。
l 善用函數索引解決狀態字段查詢,少用位圖索引
使用。位圖索引容易形成數據塊爭用,建議在OLTP系統少用。
l 悲觀鎖和樂觀鎖
悲觀鎖思想認爲,數據被併發修改的概率比較大,須要在修改以前藉助於數據庫鎖機制,先對數據進行加鎖。樂觀鎖思想認爲,數據通常是不會形成衝突的。因此在通常先將數據查出來但不加鎖,在修改回數據庫時檢查數據有沒有發生過變化,若是有則認爲更新失敗。業務場景容許失敗重試的狀況,建議多考慮使用悲觀鎖,減小鎖資源對數據庫的消耗。
l 一致讀
Oracle的數據塊被修改以前會把數據塊備份到undo表空間,這樣能夠保證sql查詢過程當中,數據被修改不會影響查詢結果。並且還可使用「閃回查詢」的技術,指定查詢庫表某個時間點的數據。
l 使用with as改寫複雜的關聯查詢
這樣好處一是簡化sql邏輯,二是有必要時還可使用hint:materialize先把with as的內容實體化,減小重複查詢。
l 索引要合理(基數太小的字段不適合建索引)
有些程序員在性別列上面都建了索引,覺得查詢時至少能夠省一半時間,實際上是錯的。由於對於這種選擇性不高的查詢,先使用索引查詢再回表查會致使不少隨機讀寫,速度反而不如直接全表掃描快。
l 大量數據遷移時加快入庫速度的方法:
commit nowait
append
alter table nologging
刪除索引
使用交換分區
l 最好對數據庫api進行封裝,以便在日誌裏面輸出使用的sql
系統作複雜後,新手想徹底瞭解系統業務很困難。若是能夠設置在日誌裏面輸出訪問數據庫使用的sql,能夠更方便咱們進行系統運維。
更多數據庫開發經驗見:
http://www.javashuo.com/article/p-bvcipkfa-gn.html 《oracle數據庫應用性能優化經驗(培訓講義)》
http://www.javashuo.com/article/p-wxiusnmm-hc.html 《Oracle Proc編程性能優化經驗》