快速入門全棧 - 07 DBMS性能優化

一、什麼是DBMS?

數據庫管理系統,Database Management System,用於建立、使用和維護數據庫,簡稱DBMS。他對數據庫進行統一的管理和控制,以保證數據庫的安全性和完整性。數據庫管理系統是一個提供數據錄入、刪除、修改、查詢的數據操作軟件,具有數據定義、數據操作、數據存儲與管理、數據維護、通信等功能。

二、Oracle數據庫硬件性能優化

Oracle數據庫是目前業界較爲成功的關係型數據庫系統,可以運行在Unix、Windows等主流操作系統平臺。

數據庫的性能取決於CPU、內存、磁盤、網絡條件。數據庫建立在多個表空間上,分爲控制文件、日誌文件、數據文件、口令文件、參數文件。

  • 磁盤讀寫進度對數據庫是至關重要的,數據庫對象在物理設備上的合理分佈可以改善性能
  • 磁盤鏡像會減慢磁盤寫的速度
  • 通過日誌文件和歸檔文件與控制文件和數據文件分離,可以提高系統性能
  • 不同的數據庫放在不同的硬盤上,建議把數據庫、回滾段、日誌放在不同設備上
  • 減少無關I/O
  • Oracle中文件類型推薦使用RAID級別

RAID通常使用在數據庫集羣上,也就是RAC模式。當數據庫訪問壓力較大時,我們需要做負載均衡。

三、操作系統參數調整

在Linux系統上,我們可以通過一系列指令來查看系統負載

cat /proc/cpuinfo
cat /proc/meminfo
df -h

我們還可以使用top和free來查看CPU和內存的使用情況

我們可以在Linux上修改用戶的Shell限制

vim /etc/security/limits.conf

oracle soft nproc 2047
oracle hard nproc 16384
oracle soft nofile 1024
oracle hard nofile 65536

nofile是最大可以打開的文件數量,nproc是單個用戶可用的最大進程數量。soft的是軟限制,hard是硬限制,用戶可以超過軟限制但一定不能超過硬限制,一般soft比hard小。

PAM驗證模塊/lib/security/pam_limits.so可以限制用戶會話過程中對各種系統資源的使用。

我們還可以修改Linux內核的shmall和shmmax參數。SHMMAX是Linux進程可以分配的單獨共享內存段的最大值,一般設置爲內存大小的一般。SHMALL設置共享內存總頁數。這個值太小了可能導致數據庫啓動報錯。

四、Oracle數據庫內存分配

自動SGA管理 (ASMM),可以自動分配Oracle使用的內存

ALTER SYSTEM SET MEMORY_MAX_TARGET = 1024M SCOPE = SPFILE;
ALTER SYSTEM SET MEMORY_TARGET = 1024M SCOPE = SPFILE;
ALTER SYSTEM SET SGA_TARGET = 1024M SCOPE = SPFILE;
ALTER SYSTEM SET PGA_AGGREGATE_TARGET = 1024M SCOPE = SPFILE;

MEMORY_TARGET是動態控制SGA和PGA時,Oracle總共可以使用的共享內存大小。
MEMORY_MAX_TARGET是定義的MEMORY_TARGET最大可以達到而不用重啓實例的值。SGA_TARGET與PGA_AGGREGATE_TARGET都設置爲0,才能開啓自動內存管理。

Oracle官方文檔推薦,MEMORY_TARGET=物理內存x80%,MEMORY_MAX_SIZE=物理內存x80%.對於OLTP西永,SGA_TARGET=(物理內存x80%)x80%,SGA_MAX_SIZE=(物理內存x80%)x80%,PGA_AGGREGATE_TARGET=(物理內存x80%)x20%。對於OLAP系統,SGA_TARGET=(物理內存x80%)x50%,SGA_MAX_SIZE=(物理內存x80%)x50%,PGA_AGGREGATE_TARGET=(物理內存x80%)x50%

五、Oracle數據結構設計

數據庫設計規範

  • 表中應該避免可爲空的列,雖然表中允許空列,但是空字段是一種特殊的數據類型
  • 表不應該有重複的值或者列
  • 表中記錄應該有一個唯一的標識符,在數據庫表設計的時候應該用一個ID來唯一地標識行記錄
  • 數據庫要有一個統一的前綴
  • 儘量只存儲單一實體類型的數據

字段的設計

  • 字段的選擇儘量避免隱式轉換導致無法使用索引。
  • 建議使用NUMBER(m,n)
  • VARCHAR2(n),n=10,20,50,100,200,500,1000,2000,4000, …
  • BLOB應該只在長度超過2000字節的時候使用
  • 謹慎使用TIMESTAMP類型,這個類做查詢的代價比較高
  • 不建議使用CHAR類型,不建議選擇LONG RAW類型

字段順序

  • 靠近記錄開始的地方字段定位速度會明顯快於記錄尾的字段
  • 常用的字段放在前面
  • 末尾的null值不保存,因此建議null字段放表末端

索引設計

  • 索引字段建議非空,如果有空值就設置一個缺省值
  • 表索引原則上在5個內
  • 單字段上索引原則上不能超過2個
  • 複合索引原則上不能超過3個字段
  • 分區表原則上全部使用LOCAL索引
  • 索引字段的選擇
    • 頻繁出現在where子句裏的字段建議建立索引
    • 用來和其他表關聯的字段建議建立索引
    • 素引字段建議有高的選擇性和過濾性
    • 對於枚舉值較少的字段,建議不要創建B-tree索引,建議建立bitmap索引
    • 在where子句裏作爲函數參數的字段,不能創建索引,不建議建立函數索引
    • 建立索引的時候,建議考慮到select和insert,update,delete的平衡
    • 一般建議在查詢數據量10%以下使用索引

複合索引字段

  • 增加索引選擇性,降低I/O
  • where子句的查詢條件構成索引字段前沿列
  • 將頻繁查詢的字段放在前面
  • 如果所有字段查詢頻率相同,則把選擇性好的字段放在前面
  • 如果所有字段查詢頻率相同,則把表中數據的排列順序所依據的字段放在前面

六、Oracle SQL語句優化

根據下面的方法,來提升SQL語句的執行效率

  • 對於分區表的查詢,原則上使用分區表
  • 必要時,使用hint固定關鍵SQL語句執行計劃,原則上批量作業要用hint指定索引
  • 對於關鍵SQL語句,儘量簡化,不要包含太多層次,原則上不超過2層
  • 使用綁定變量,減少數據庫硬解析
  • 字符型字段建議加單引號,避免where查詢條件做隱形轉換後出現混亂
  • 儘量減少in的使用
  • 使用union的時候如果沒有混合數據邏輯建議使用union all代替
  • 注意like的使用方法,%變量%及%變量是用不到索引的,變量%要注意查詢範圍,%放到越靠後使用索引範圍越大
  • commit不能單步提交,建議100-1000做一次提交
  • snapshot too old 錯誤原則是跟數據庫無關,大多是select效率低引起
  • 動態sql儘量少用,容易產生大量硬解析,並造成library cache pin等待
  • where子句中,如果索引列是函數的一部分,優化器將不使用索引而使用全表掃描
  • 用>=替代>,用UNION替代OR,用IN代替OR
  • IN和NOT IN也要慎用
  • 用exists代替in,DISTINCT
  • 避免在索引列上使用IS NULL和IS NOT NULL
  • 避免改變索引列的類型
  • 減少使用select * 來進行查詢
  • 擺放where子句時,把能過濾大量數據的條件放在最下邊,where執行會從下往上執行
  • 用TRUNCATE替代DELETE
  • 用內部函數提高SQL效率

我和幾位大佬建立了一個微信公衆號,歡迎關注後查看更多技術乾貨文章
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章