|
一、前言 2 二、ORACLE數(shù)據(jù)庫優(yōu)化概述 2 1、內(nèi)存等參數(shù)配置的優(yōu)化 3 2、減少物理讀寫的優(yōu)化 4 3、批量重復(fù)操作的SQL語句及大表操作的優(yōu)化 4 二、ORACLE數(shù)據(jù)庫優(yōu)化方案 5 1、內(nèi)存等Oracle系統(tǒng)參數(shù)配置 5 2、使用索引 6 3、表分區(qū) 8 4、Procedure優(yōu)化 9 5、其他改造 10 6、維護(hù)作業(yè)計劃 10 三、ORACLE數(shù)據(jù)庫優(yōu)化前后比較 10 1、批量重復(fù)的SQL語句執(zhí)行性能 10 2、一些單次、不常用的操作的語句執(zhí)行性能 11 四、參考 11 1、常用的優(yōu)化工具 11 2、參考文獻(xiàn) 12
一、前言 隨著實際項目的啟動,實際項目中使用的 Oracle數(shù)據(jù)庫經(jīng)過一段時間的運行,在線保存的數(shù)據(jù)量和業(yè)務(wù)處理的數(shù)據(jù)量在逐漸增大,最初的Oracle設(shè)置,與現(xiàn)在實際需要的運行性能有一定差距,需要進(jìn)行一些優(yōu)化調(diào)整。 本文將結(jié)合本人實際維護(hù)經(jīng)驗,相應(yīng)地提出實際項目數(shù)據(jù)處理的一些優(yōu)化方法,以供參考。 適用于Oracle 9i。
二、Oracle數(shù)據(jù)庫優(yōu)化概述 Oracle數(shù)據(jù)庫的優(yōu)化,針對不同的應(yīng)用,會有側(cè)重點不同的優(yōu)化方法,根據(jù)我們實際項目的應(yīng)用特點,我們主要關(guān)心的是每次事務(wù)執(zhí)行完成的時間長短。 從Oracle數(shù)據(jù)庫本身的特點,我們可以把優(yōu)化工作劃分為初始優(yōu)化設(shè)置,微優(yōu)化。 在初始優(yōu)化設(shè)置時,我們只能根據(jù)硬件情況,估計業(yè)務(wù)運行的情況,綜合經(jīng)驗,給出一種經(jīng)驗設(shè)置,大體上來說,這種經(jīng)驗設(shè)置離滿足優(yōu)化需求的目標(biāo)不是很遠(yuǎn)。 在完成了初始優(yōu)化設(shè)置后,經(jīng)過一段時間的業(yè)務(wù)運行,已可開始收集實際運行環(huán)境的性能數(shù)據(jù),此時,就可以對各種Oracle性能指標(biāo)、各種關(guān)心的事務(wù)操作進(jìn)行性能評估,然后進(jìn)行微優(yōu)化了。 Oracle
優(yōu)化,不是一個一蹴而就的工作,也不是一個一勞永逸的工作,需要定期維護(hù),定期觀察,在發(fā)現(xiàn)性能瓶頸時及時進(jìn)行調(diào)整。Oracle總是存在性能瓶頸的,不
使用、不操作的數(shù)據(jù)庫總是最快的,在解決當(dāng)前瓶頸后,總是會有另一個瓶頸出現(xiàn),所以在優(yōu)化前,我們需要確定一個優(yōu)化目標(biāo),我們的目標(biāo)是滿足我們的應(yīng)用性能
要求就可以了。 Oracle優(yōu)化,涉及的范圍太廣泛,包含的有主機(jī)性能,內(nèi)存使用性能,網(wǎng)絡(luò)傳輸性能,SQL語句執(zhí)行性能等等,從我們面向網(wǎng)管來說,滿足事務(wù)執(zhí)行速度性能主要表現(xiàn)在: 1)批量重復(fù)的SQL語句執(zhí)行性能(主要是通過Procedure計算完成數(shù)據(jù)合并和數(shù)據(jù)匯總的性能和批量數(shù)據(jù)采集入庫的性能); 2)一些單次、不常用的操作的語句執(zhí)行性能(主要是GUI的非規(guī)律操作)。 根據(jù)這兩個特點,我們可把優(yōu)化方法歸納到3個重要方向: 1)內(nèi)存等參數(shù)配置的優(yōu)化。內(nèi)存優(yōu)化,是性能受益最快的地方。 2)減少物理讀寫的優(yōu)化。內(nèi)存邏輯I/O操作的時間,遠(yuǎn)遠(yuǎn)小于物理I/O的操作時間。 3)批量重復(fù)操作的SQL語句及大表操作的優(yōu)化。減少SQL執(zhí)行次數(shù),減少大表操作次數(shù)。 下面主要針對得益最大的這三個方向的優(yōu)化進(jìn)行闡述。 1、內(nèi)存等參數(shù)配置的優(yōu)化 對
于大多數(shù)應(yīng)用來說,最直接、最快速得到優(yōu)化收益的,肯定屬于內(nèi)存的優(yōu)化。給每個Oracle內(nèi)存塊分配合理的大小,可以有效的使用數(shù)據(jù)庫。通過觀察各種數(shù)
據(jù)庫活動在內(nèi)存里的命中率,執(zhí)行情況,我們能很快的掌握數(shù)據(jù)庫的主要瓶頸。我們從下面的一條SQL語句的執(zhí)行步驟就可知道。 一個SQL語句,從發(fā)布到執(zhí)行,會按順序經(jīng)歷如下幾個步驟: 1)Oracle把該SQL的字符轉(zhuǎn)換成它們的ASCII等效數(shù)字碼。 2)該ASCII數(shù)字碼被傳送給一個散列算法,生成一個散列值。 3)用戶server process查看該散列值是否在shared pool內(nèi)存塊中存在。 若存在: 4)使用shared pool中緩存的版本來執(zhí)行。 若不存在: 4)檢查該語句的語義正確性。 5)執(zhí)行對象解析(這期間對照數(shù)據(jù)字典,檢查被引用的對象的名稱和結(jié)構(gòu)的正確性)。 6)檢查數(shù)據(jù)字典,收集該操作所引用的所有對象的相關(guān)統(tǒng)計數(shù)據(jù)。 7)準(zhǔn)備執(zhí)行計劃,從可用的執(zhí)行計劃中選擇一個執(zhí)行計劃。(包括對stored outline和materialized view的相關(guān)使用的決定) 8)檢查數(shù)據(jù)字典,確定所引用對象的安全性。 9)生成一個編譯代碼(P-CODE)。 10)執(zhí)行。 這里,通過內(nèi)存的合理分配,參數(shù)的合理設(shè)置,我們主要解決: 1)減少執(zhí)行到第五步的可能,節(jié)約SQL語句解析的時間。第五步以后的執(zhí)行過程,是一個很消耗資源的操作過程。 2)通過內(nèi)存配置,盡可能讓SQL語句所做的操作和操作的數(shù)據(jù)都在內(nèi)存里完成。大家都知道,從內(nèi)存讀取數(shù)據(jù)的速度,要遠(yuǎn)遠(yuǎn)快于從物理硬盤上讀數(shù)據(jù),一次內(nèi)存排序要比硬盤排序快很多倍。 3)根據(jù)數(shù)據(jù)庫內(nèi)存活動,減少每個內(nèi)存塊活動的響應(yīng)時間,充分利用每個內(nèi)存塊,減少內(nèi)存latch爭用發(fā)生的次數(shù)。 2、減少物理讀寫的優(yōu)化 無論如何配置Oracle數(shù)據(jù)庫,我們的網(wǎng)管系統(tǒng),每小時周期性的都會有新數(shù)據(jù)被處理,就會發(fā)生物理讀寫,這是避免不了的。 減少物理讀寫的優(yōu)化,一般所用的方法有: 1) 增加內(nèi)存data buffer的大小,盡可能讓數(shù)據(jù)庫操作的數(shù)據(jù)都能在內(nèi)存里找到,不需要進(jìn)行物理讀寫操作。 2) 通過使用索引,避免不必要的全表掃描。 3) 大表物理分區(qū),Oracle具有很好的分區(qū)識別功能,減少數(shù)據(jù)掃描范圍。 上述3個方法,是從整體上改善數(shù)據(jù)庫物理I/O性能最明顯的3個方法。能非??焖俚臏p少數(shù)據(jù)庫在物理I/O,最直接的反應(yīng)是數(shù)據(jù)庫事務(wù)執(zhí)行時間能能以數(shù)量級為單位減少。 其
他的一些減少物理讀寫的優(yōu)化方法,比如使用materialized view,Cluster等方法;還有一些分散I/O的方法,比如
Oracle日志文件不與數(shù)據(jù)文件放在一個物理硬盤,數(shù)據(jù)熱點文件物理I/O分開等等方法,就目前我們的網(wǎng)管系統(tǒng)而言,能得到的效果不是很明顯,在網(wǎng)管系
統(tǒng)中,為了不增加數(shù)據(jù)庫維護(hù)的復(fù)雜性,不推薦使用。 3、批量重復(fù)操作的SQL語句及大表操作的優(yōu)化 批量重復(fù)執(zhí)行的SQL語句,一般出現(xiàn)在每個周期時間內(nèi)的數(shù)據(jù)批量入庫的insert語句,和數(shù)據(jù)合并、匯總的周期性select、delete、insert操作。 我們需要注意以下幾點: 1) 減少不必要的SQL語句執(zhí)行和SQL語句的執(zhí)行次數(shù)。 每條SQL語句執(zhí)行,都會消費系統(tǒng)資源,都有執(zhí)行時間。減少不必要的SQL語句執(zhí)行和減少SQL語句的執(zhí)行次數(shù),自然能減少業(yè)務(wù)執(zhí)行時間。需要根據(jù)業(yè)務(wù)流程,重新設(shè)計數(shù)據(jù)處理的代碼。此方法主要適用于procedure執(zhí)行的數(shù)據(jù)合并、匯總。 2) 這些SQL語句,由于每個SQL語句都要執(zhí)行很多次,應(yīng)該盡量讓該SQL的散列值在shared pool內(nèi)存塊中存在。也就是使用動態(tài)SQL,避免SQL硬解析。 可通過Oracle參數(shù)的設(shè)置,和動態(tài)SQL語句的應(yīng)用,通過綁定變量的方式,減少SQL語句的解析次數(shù)。 3) 減少大表的操作,確保在一次事務(wù)中,同類操作只對大表執(zhí)行一次。主要在數(shù)據(jù)合并和數(shù)據(jù)匯總的pprocedure和數(shù)據(jù)采集時出現(xiàn)。 -
procedure:在我們的應(yīng)用中,cell數(shù)據(jù)和traffic數(shù)據(jù),以及l(fā)ink,linkset,trunkgroup等數(shù)據(jù),都屬于大數(shù)據(jù)量業(yè)
務(wù),對他們的每次操作,執(zhí)行的時間都不短(即使做了表分區(qū),減少數(shù)據(jù)掃描范圍,操作的響應(yīng)時間還是大于一個同類大小的普通表)。在多次執(zhí)行的一個
procedure中,通過使用臨時表的方式,把多次大表操作,改造成一次大表操作,能極大的縮短業(yè)務(wù)執(zhí)行時間。 - 數(shù)據(jù)采集:如果是普通的每條insert語句完成一條數(shù)據(jù)入庫,為了保證數(shù)據(jù)的唯一性,每次入庫的時候,都會判斷該條數(shù)據(jù)是否存在數(shù)據(jù)庫,造成對表不必要的多次操作。對于批量數(shù)據(jù)入庫,我們推薦使用sqlldr的方法進(jìn)行數(shù)據(jù)拷貝,能極大的提高數(shù)據(jù)入庫時間。 二、Oracle數(shù)據(jù)庫優(yōu)化方案 1、內(nèi)存等Oracle系統(tǒng)參數(shù)配置 Oracle 的parameter參數(shù),分動態(tài)參數(shù)和靜態(tài)參數(shù),靜態(tài)參數(shù)需要重新啟動數(shù)據(jù)庫才能生效,動態(tài)參數(shù)不需要重新啟動數(shù)據(jù)庫即可生效。 Oracle 9i可以使用spfile的特性,使用alter system set 參數(shù)名=參數(shù)值 scope=both[spfile];的方法進(jìn)行修改。也可以直接修改pfile。 以下給出了網(wǎng)管Oracle 數(shù)據(jù)庫重點關(guān)注的parameter的初始優(yōu)化設(shè)置。 最大可使用的內(nèi)存SGA總和 靜態(tài)參數(shù)sga_max_size=物理內(nèi)存的大小減1.5G Shared pool 動態(tài)參數(shù)shared_pool_size= 600 ~ 800 M 靜態(tài)參數(shù)shared_pool_reserved_size= 300 M 動態(tài)參數(shù)open_cursors= 400 ~ 600 靜態(tài)參數(shù)cursor_space_for_time= TRUE 靜態(tài)參數(shù)session_cached_cursors= 60 ~ 100 動態(tài)參數(shù)cursor_sharing= SIMILAR Data buffer 動態(tài)參數(shù)db_cache_advice= READY 動態(tài)參數(shù)db_cache_size 動態(tài)參數(shù)Db_keep_cache_size 動態(tài)參數(shù)db_recycle_cache_size (sga_max_size大小,除了分配給所有非data buffer的size,都分配給data buffer) Sga other memory 動態(tài)參數(shù)large_pool_size= 50 M 靜態(tài)參數(shù)java_pool_size= 100 M 動態(tài)參數(shù)log_buffer= 3 M Other memory 動態(tài)參數(shù)sort_area_size= 3 M 靜態(tài)參數(shù)sort_area_retained_size= 0.5 M 靜態(tài)參數(shù)pga_aggregate_target= 800 M 動態(tài)參數(shù)workarea_size_policy= AUTO 磁盤I/O配置 靜態(tài)參數(shù)sql_trace= FALSE 動態(tài)參數(shù)timed_statistics= true 動態(tài)參數(shù)db_file_multiblock_read_count= 16 靜態(tài)參數(shù)dbwr_io_slaves= 0 靜態(tài)參數(shù)db_writer_processes= 3 靜態(tài)參數(shù)undo_management= AUTO 動態(tài)參數(shù)undo_retention= 7200 2、使用索引 我們初步定義,表數(shù)據(jù)超過1000行的表,我們都要求使用索引。(不區(qū)分事務(wù)操作的數(shù)據(jù)在表數(shù)據(jù)中所占的比例) 索引所包含的字段不超過4個。 檢查SQL語句是否使用了索引,我們使用execute plan來看,獲得explain的方法,我們通過SQL*PLUS工具,使用如下命令進(jìn)行查看: set autotrace on set autotrace traceonly explain set timing on 或通過SQL*PLUS trace,然后查看user_dump_dest下的跟蹤文件,使用tkprof工具格式化后閱覽。 alter session set events '10046 trace name context forever,level 12'; alter session set events '10046 trace name context off'; SELECT p.spid,s.username FROM v$session s,v$process p WHERE s.audsid=USERENV('sessionid') AND s.paddr = p.addr; 使用方法示例: DBserver% sqlplus perf/perf SQL*Plus: Release 9.2.0.6.0 - Production on Mon Oct 17 14:32:29 2005 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. Connected to: Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production With the Partitioning, OLAP and Oracle Data Mining options JServer Release 9.2.0.6.0 - Production SQL> set timing on SQL> set autotrace on SQL> select count(*) from perf_sdcch_nn where start_time = (select max(start_time) from perf_sdcch_nn); COUNT(*) ---------- 638 Elapsed: 00:00:00.80 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=8) 1 0 SORT (AGGREGATE) 2 1 INDEX (RANGE SCAN) OF 'IDX02_PERF_SDCCH_NN' (NON-UNIQUE) (Cost=2 Card=1495 Bytes=11960) 3 2 SORT (AGGREGATE) 4 3 INDEX (FULL SCAN (MIN/MAX)) OF 'IDX02_PERF_SDCCH_NN' (NON-UNIQUE) (Cost=1 Card=3852090 Bytes=30816720) Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 15 consistent gets 0 physical reads 0 redo size 492 bytes sent via SQL*Net to client 656 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed SQL> 從上面的示例我們可以看到,該SQL語句執(zhí)行花了0.8秒,select語句和inline view,都使用了名為'IDX02_PERF_SDCCH_NN 的索引。物理讀為0,redo log size為0,沒有生成REDO日志。
3、表分區(qū) 在網(wǎng)管數(shù)據(jù)庫里,比較突出的大表有小區(qū)表和告警表。 性能表,使用范圍分區(qū)。 以時間點start_time為范圍分區(qū)字段。 告警表,使用range-hash的混合分區(qū)和范圍分區(qū)。 范圍分區(qū)以時間點starttime為分區(qū)字段,混合分區(qū)增加ALARMNUMBER為字段的hash子分區(qū)。 同時,創(chuàng)建本地分區(qū)索引。 范圍分區(qū)示范: drop table part_mid_cell_traf; create table part_mid_cell_traf; ( NE_ID CHAR(16) NOT NULL, .................... TCHSEIZE FLOAT(126) ) partition by range(start_time) ( partition
mid_cell_traf_051225 values less than (to_date('2005-12-25
00:00:00','yyyy-mm-dd hh24:mi:ss')) tablespace perf_partition42, partition
mid_cell_traf_051230 values less than (to_date('2005-12-30
00:00:00','yyyy-mm-dd hh24:mi:ss')) tablespace perf_partition43, partition mid_cell_traf_error values less then (maxvalue) tablespace perf_partition44 ) enable row movement; CREATE INDEX local_mid_cell_traf ON part_mid_cell_traf (ne_id,cell_id,start_time,stop_time) LOCAL ( partition l_ind1_mid_cell_traf_051225 tablespace perf_partition42, partition l_ind1_mid_cell_traf_051230 tablespace perf_partition43, partition l_ind1_mid_cell_traf_error tablespace perf_partition44 ); Range-hash混合分區(qū)示范: create table part_ALARMTEXTDATA; ( ALARMNUMBER VARCHAR2(16) NOT NULL, ...... SERIAL NUMBER(38) NOT NULL ) partition by range (STARTTIME) subpartition by hash(ALARMNUMBER) subpartition template ( subpartition atd01 tablespace alarm_partition01, subpartition atd02 tablespace alarm_partition02, subpartition atd03 tablespace alarm_partition03, ) ( partition ALARMTEXTDATA_051225 values less than (to_date('2005-12-25 00:00:00','yyyy-mm-dd hh24:mi:ss')), partition ALARMTEXTDATA_051230 values less than (to_date('2005-12-30 00:00:00','yyyy-mm-dd hh24:mi:ss')), partition ALARMTEXTDATA_error values less then (maxvalue) ) enable row movement;
CREATE INDEX local_ALARMTEXTDATA ON ALARMTEXTDATA (STARTTIME,ALARMNUMBER,SERIAL) LOCAL ( partition l_ind1_atd_050910 tablespace alarm_partition02, partition l_ind1_atd_050915 tablespace alarm_partition03, partition l_ind1_atd_050920 tablespace alarm_partition04, ); 4、Procedure優(yōu)化 1)取消地市一級的Procedure,只保留其上層調(diào)用Procedure,并保持參數(shù)輸入方法,調(diào)用方法不變。 2)確保大表數(shù)據(jù)查詢操作只有1次,確保大表數(shù)據(jù)刪除只有一次。 3)確保單條SQL語句執(zhí)行已優(yōu)化。 4)減少SQL執(zhí)行次數(shù)。
5、其他改造 修改表存儲參數(shù),提前預(yù)先分配extents。 修改表空間存儲參數(shù)(采集表空間所用塊設(shè)置為大塊,比如32k一個塊;修改ptcfree,pctused,pctincrease等)。 避免使用唯一索引和非空約束。 創(chuàng)建合理的索引。 各模塊SQL語句優(yōu)化,比如使用提示固定索引等。 確認(rèn)每一條歷史數(shù)據(jù)刪除語句已優(yōu)化和刪除方法。 臨時表的使用。 6、維護(hù)作業(yè)計劃 表分析(包含確定具體的表的分析方法,分區(qū)表分析方法,索引分析方法)。 空間回收維護(hù)(包括確定HWM,回收多余分配給表的塊,合并數(shù)據(jù)塊碎片等)。 索引維護(hù)(包括定期重建索引,索引使用情況監(jiān)視等)。 歷史數(shù)據(jù)刪除檢查(檢查保存的數(shù)據(jù)是否符合要求,檢查歷史數(shù)據(jù)刪除方法是否正確-比如批量刪除提交的方法等)。 全庫性能分析和問題報告及優(yōu)化(比如使用statspack進(jìn)行性能趨勢分析,檢查有問題的SQL或事務(wù),確定當(dāng)前系統(tǒng)等待的top 5事件等等)。 表數(shù)據(jù)keep,default及reclye(比如把一些常用的配置表固定在內(nèi)存里等)。 數(shù)據(jù)庫參數(shù)核查(防止數(shù)據(jù)庫參數(shù)被修改,定期對系統(tǒng)配置參數(shù)進(jìn)行比較)。 日志文件分析(定期檢查Oracle生成的日志文件,定期備份、刪除)。 硬盤空間維護(hù)(定期對Oracle 對象使用的空間情況進(jìn)行監(jiān)視)。 三、Oracle數(shù)據(jù)庫優(yōu)化前后比較 1、批量重復(fù)的SQL語句執(zhí)行性能 根據(jù)網(wǎng)元數(shù)量,各地的執(zhí)行的完成時間有所區(qū)別。 用于數(shù)據(jù)合并和匯總的Procedure的計算性能 通過statspack的周期性采集數(shù)據(jù),我們可以使用以下語句,計算我們想統(tǒng)計的Procedure的執(zhí)行情況: SELECT TO_CHAR(sn.snap_time,'yyyy-mm-dd hh24:mi:ss') AS snap_time,s.disk_reads, s.buffer_gets,s.elapsed_time/1000000 AS elapsedtime FROM (SELECT hash_value,sql_text,address,last_snap_id FROM STATS$SQLTEXT WHERE piece = 0 AND sql_text LIKE '%&sqltext_key%') t, (SELECT address,hash_value,snap_id,sql_text,disk_reads,executions, buffer_gets,rows_processed,elapsed_time FROM STATS$SQL_SUMMARY) s,STATS$SNAPSHOT sn WHERE s.hash_value = t.hash_value AND s.address = t.address AND s.snap_id = t.last_snap_id AND sn.snap_id = s.snap_id; 比如,我們以perfstat用戶執(zhí)行該SQL,輸入“to_comp”,可以觀察到數(shù)據(jù)庫里保存的有的to_comp存儲過程的執(zhí)行時間,我們發(fā)現(xiàn),其執(zhí)行時間,從優(yōu)化前的幾千秒,最后穩(wěn)定在優(yōu)化后的幾十秒。 注:to_comp是整體調(diào)用執(zhí)行一次所有網(wǎng)元的數(shù)據(jù)合并和匯總的procedure。
用于小區(qū)分析數(shù)據(jù)的Procedure的計算性能 使用上面的方法,我們一樣可以知道,小區(qū)分析的procedure執(zhí)行,從優(yōu)化前的約幾千秒,最后穩(wěn)定在優(yōu)化后的幾十秒。 批量數(shù)據(jù)采集入庫性能 使用bcp,能從以前約15分鐘,減少到約4分鐘。 2、一些單次、不常用的操作的語句執(zhí)行性能 GUI上的性能數(shù)據(jù)查詢,告警數(shù)據(jù)查詢,響應(yīng)時間都極快,幾乎不再出現(xiàn)長時間等待響應(yīng)的情況。 四、參考 1、常用的優(yōu)化工具 statspack sql*plus TOAD 2、參考文獻(xiàn) Oracle online document Oracle company release
bigboar
發(fā)表于:2006.02.15 16:12
(###)
|