【轉】Oracle性能調優-優化排序操作

  關於Oracle 10g性能方面,談論最多的就是新的自動工作負荷存儲庫(AWR)特性和通過自動數據庫診斷監視(ADDM)提供的前瞻性性能監視。
  當建立同Oracle會話時,會在服務器內存中劃分出一個專門用來排序的區域,從而爲會話提供排序空間。但是,這個排序空間畢竟有限,若記錄數量超 過這個排序空間的話,就需要進行磁盤排序。但是,我們都知道,磁盤排序的執行速度要比內存排序的執行速度慢1400倍。而且,磁盤排序會消耗臨時表空間的 資源,並且可能影響到正在進行的其他SQL排序,因爲Oracle必須爲臨時表空間中的數據塊分配緩衝池。而且,過多的磁盤排序會導致空閒緩衝等待,以及 將執行其他任務的數據塊從緩衝池中分頁出去。對於數據庫管理員來說,在內存中進行排序總是比磁盤排序更受歡迎。所以說,磁盤排序是影響Oracle數據庫 性能的罪魁禍首。
  在數據庫優化的時候,我們應該想法設法降低數據庫的磁盤排序。爲此,筆者有如下建議。
  一、合理設置Sort_area_size參數。
  雖然說Oracle10G以後的數據庫會自動對內存進行管理。但是,在一些性能要求比較高或者排序頻率比較高的數據庫中,仍然有必要對一些影響內存分配的參數進行調整。其中,最重要的一個參數就是Sort_area_size。
  Oracle數據庫會爲所有的鏈接Oracle會話分配Sort_area_size這個參數。所以,對於擁有大量用戶的數據庫來說,如果增加 這個參數的值,會讓磁盤排序的機率明顯降低,不過數據庫也要爲此付出這個代價,很容易導致內存過載。但是,如果這個參數的值設置的過低的話,又會導致過多 的磁盤排序。
  所以,這個參數並不是越大越好。因爲這個參數如果設置的過大的話,其帶來的性能收益反而會降低。因爲爲了提高有限幾個查詢的速度,可能會浪費大量的內存。這無疑是我們數據庫管理員不希望看到的。
  在實際工作中,我們往往需要在兩者之間進行一個均衡。設置一個合理的參數,儘量讓數據庫減少磁盤排序的機率,同時也不能使得服務器內存過載。
  爲此筆者有一個建議。數據庫管理員應該每隔一段時間增加這個參數的值,並使用Statspack工具定時監控內存排序與磁盤排序的數據。在起初進行調整的時候最好每個小時查詢一次。通過這些數據,我們就可以得到一個合理的參數值,在兩這之間取得一個均衡。
  前期調整完成後,在後期仍然需要進行監控。因爲後期隨着企業應用的改變,這個參數仍然需要根據實際情況進行調整,以提高數據庫的性能。
  二、儘量減少不必要的排序。
  在某些情況下,儘管數據庫管理員沒有直接通過Order By等語句對數據庫記錄進行排序,可是Oracle數據庫服務器仍然會對查詢結果進行排序。因爲這些語句需要起作用,必須要先對數據進行排序。所以,他們往往帶有隱性的排序功能。
  我們在數據庫維護或者前臺應用程序設計的時候,要儘量的減少這種不必要的排序。如Distinct關鍵字,它的作用就是取消重複的記錄。但是, 要實現這個目的的話,則數據庫必須要先對記錄進行排序,然後才能夠去除重複的記錄內容。故在設計的時候,儘量要避免使用Distinct關鍵字。其實,筆 者在工作中,經常會碰到這種情況,某些記錄其實不存在重複記錄,但是程序開發人員爲了保障數據的準確性,就在SQL語句中加入了Distinct關鍵字, 從而造成了不必要的排序。
  另外,在其他一些情況下,也會導致不必要的排序。如排序合併連接,也會導致不必要的排序。故無論何時,只要使用了排序合併連接,就會執行排序已 連接關鍵值。故在數據庫與應用程序設計的時候,要儘量避免排序合併連接。其實,在許多情況下,嵌套循環連接反而使更好的選擇。因爲這個嵌套循環連接,它更 加有效而且不會導致不必要的排序以及不比要的全表掃描。
  其次,有時候缺失索引也會導致一些並不要的排序。
  故數據庫管理員在平時的工作中,要儘量的減少這些不必要的排序,以讓寶貴的內存資源交給更重要的任務來適用。
  三、利用Statspack工具監控排序活動。
  Statspack工具是一款提高Oracle數據庫性能的很好的輔助工具。因爲它可以幫助我們收集很多有用的信息。故我們數據庫管理員也可以利用Statspack工具對數據庫中的排序活動進行監控。
對於一個有經驗的數據庫管理員來說,對內存排序和磁盤排序保持必要的排需是非常必要的。因爲我們無法左右用戶的行爲;而用戶的行爲又會有所調整。用 戶在調整的過程中,有可能又會增加額外的磁盤排序。當然,也有可能磁盤排序的機率會減少。但是,通常情況下,隨着用戶交易數據的增加,這個磁盤排序的機率 在理論上仍然是往上爬的。而實際上也是往上升的,只是這個升的速度沒有理論上那麼快而已。這主要是看數據庫管理員如何進行管理了。
  根據筆者的瞭解,企業用戶的操作往往會有一個週期性的變化,如按年或者按月進行週期性的變化。數據庫管理員應該養成一個好習慣,每個月利用Statspack工具定期的對數據庫進行監控。特別是要監控數據庫的排序情況。
   Statspack工具還有額外的一個功能,就是自動監測與警告功能。也就是說,可以讓Statspack這個工具在磁盤排序數量超過一個預設置的閥值 時,自動給數據庫管理員發送一個警告,如通過郵件形式發送給管理員等等。筆者通過監控發現,每到月底與月初的時候,磁盤排序的數量會大大的增加。這主要是 因爲在月底的時候,用戶會對當月的交易數據進行統計。所以當月底月初的時候,由於交易記錄比較多,所以,會有比較多的磁盤排序發生。在這種情況下,數據庫 管理員有必要對相關參數進行調整。不過這個調整是暫時的調整,等到這個週期過去後,仍然要把參數調回來。只有如此,數據庫的整體性能纔會有所保障。即不會 因爲內存過載而降低數據庫性能;也不會因爲磁盤排序而給數據庫造成額外的負擔。
  所以,雖然排序是SQL語句執行中很微小的一個部分,但 是其對數據庫性能影響卻比較大,而且也是非常顯著的。可惜的是,排序是SQL調整中往往被忽視的地方。在Oracle數據庫中,排序對用戶來說是透明的。 也就是說,排序對用戶很少有所限制,用戶可以根據自己的需要來對數據進行隨意地排序。但是,用戶並不知道,什麼樣的操作會降低數據庫的性能。故如何降低用 戶的不合理操作而產生額外的排序,甚至是磁盤排序,這是數據庫管理員在平時工作中必須要考慮到的一個問題。通過以上三個方法,或許可以給數據庫管理員找到 一些解決問題的思路。相信通過以上方法,可以最大程度的減少磁盤排序的發生,不再讓磁盤排序成爲影響數據庫性能的罪魁禍首。
優化排序操作
    1、概念
    服務器首先在sort_area_size指定大小的內存區域裏排序,如果所需的空間超過sort_area_size,排序會在臨時表空間裏進行。在專 用服務器模式下,排序空間在PGA中,在共享服務器模式下,排序空間在UGA中。如果沒有建立large pool,UGA處於shared pool中,如果建立了large pool,UGA就處於large pool中,而PGA不在sga中,它是與每個進程對應單獨存在的。
     PGA:program global area,爲單個進程(服務器進程或後臺進程)保存數據和控制信息的內存區域。PGA與進程一一對應,且只能被起對應的進程讀寫,PGA在用戶登錄數據庫創建會話的時候建立。
    有關排序空間自動管理的兩個參數:
    Pga_aggregate_target: 10M-4000G,等於分配給oracle instance的所有內存減去SGA後的大小。
    Workarea_size_policy: auto/manual,只有Pga_aggregate_target已定義時才能設置爲auto。
    這兩個參數會取代所有的*_area_size參數。
    措施:
    儘可能避免排序;儘可能在內存中排序;分配合適的臨時空間以減少空間分配調用。
    2、需要進行排序的操作:
    A、創建索引;
    B、涉及到索引維護的並行插入
    C、order by或者group by(儘可能對索引字段排序)
    D、Distinct
    E、union/intersect/minus
    F、sort-merge join
    G、analyze命令(僅可能使用estamate而不是compute)
    3、診斷和措施
    Select * from v$sysstat where name like ‘%sort%’;
    Sort(disk):要求Io去臨時表空間的排序數目
    Sort(memory):完全在memory中完成的排序數目
    Sort(rows):被排序的行數合計
    Sort(disk)/ Sort(memory)<5%,如果超過5%,增加sort_area_size的值。
SELECT disk.Value disk,mem.Value mem,(disk.Value/mem.Value)*100 ratio FROM v$sysstat disk,v$sysstat mem WHERE mem.NAME=’sorts (memory)’ AND disk.NAME=’sorts (disk)’;
      DISK        MEM      RATIO
———- ———- ———-
       182   27333829 0.00066584
    4、監控臨時表空間的使用情況及其配置
    Select tablespace_name,current_users,total_extents,used_extents,extent_hits,max_used_blocks,max_sort_blocks FROM v$sort_segment ;
    Column Description
    CURRENT_USERS Number of active users
    TOTAL_EXTENTS Total number of extents
    USED_EXTENTS Extents currently allocated to sorts
    EXTENT_HITS Number of times an unused extent was found in the pool
    MAX_USED_BLOCKS Maximum number of used blocks
    MAX_SORT_BLOCKS Maximum number of blocks used by an individual sort
    臨時表空間的配置:
    A、initial/next設置爲sort_area_size的整數倍,允許額外的一個block作爲segment的header
    B、pctincrease=0
    C、基於不同的排序需要建立多個臨時表空間
    D、將臨時表空間文件分散到多個磁盤上

轉自:http://boyun.sh.cn/bio/?p=851

另一個網址的:
1。 使用並行參數,8個CPU, 可以用parallel 6 ,最多佔用6個CPU, 正常情況下沒問題(前提是其他應用沒有佔超過2個CPU的資源)
2。 nologging, 絕對應該使用,會使速度大幅上升。(減少大量redo log)
3。 PGA, 普通的auto pga最大才100M, 顯然沒有達到最好性能,應該使用manual pga
alter session set workarea_size_policy=manual;
alter session set  hash_area_size=100000; -- hash_area_size 默認情況下會自動根據sort_area_size*2來調,導致sort_area_size不能超過1G, 手動設了就沒問題了。
alter session set sort_area_size=2000000000; -- 在系統可用內存足夠的情況下,最大可以到2G
4。 設置高一點的db_file_multiblock_read_count 也有利於提高I/O性能。保證足夠大的db_cache_size可以避免free_buffer_wait的出現
5。 可以通過v$session_longops 來監視進度

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章