Application Tuning
1、選擇適當的物理結構:為了達到讀寫盡可能快的目的,必須考慮下面的問題:
1)如果application對rows的訪問是按照groups進行的,則需要考慮使用clusters的方式才存儲,但clusters對于大量的DML操作會影響性能,所以要考慮application中DML和select操作的數量。
2)對于較大規模的表,使用單獨的表空間。對于一個partitioned表,考慮使用多個表空間,從而平均分配磁盤的使用。
3)對于9i中可以允許在同一個DB中有多block size,因此,row size較大的可以有較大的block size。如果設置較大的block size,有助于全表掃描的應用的性能提高。
4)對于小的small transaction占用undo space的回滾信息少,大transaction占用的undo space多,所以所需的free undo space多。
5)對于較大的查詢,可以考慮使用多server 進程進程并發查詢。
2、數據的訪問方法:為了提高性能,可以使用下面的數據訪問方法:clusters;indexes:b-tree(普通和翻轉關鍵字)、位圖、Function based;索引組織表;固化視圖。
1)Clusters:是將一組一個或多個因為有共享columns所以有相同數據塊的表放在一起的方法。這些數據塊會經常被同時訪問或join。這種方法可以使DBA對數據庫非規范化,而對user和programmer是透明的。
它在一定程度上降低了磁盤I/O,使用clustered table可以很好的改善join的效率。每個cluster關鍵字對于多行且值相同的情況下,只會存儲一次,所以占用存儲空間較小。
但是對于全表掃描,clustered表比nonclustered 表慢很多。
cluster的類型有:
①index cluster:它使用一個被稱作cluster index的索引維持cluster中的數據。在index cluster中,對數據的維護、訪問、存儲cluster index必須是可用的。cluster index用于指向包含給定關鍵字值的rows的block位置。與普通index不同的是cluster indexes會存儲null 值。對于每個cluster index中的關鍵字,只有一條記錄。所以一個cluster index會比普通index的占用空間小。
②hash clusters:它使用hash算法(也已user定義,也可系統指定)計算row的位置。用于查詢和DML操作。對于等值查找clusters key,hash cluster的性能要比index cluster的好。
不應使用clusters的情況:經常執行全表掃描的情況;如果對于所有rows的cluster key的數據超出了一到兩個Oracle blocks,這樣,為了訪問在clustered key table中的一條row,Oracle server需要讀取有相同值的所有blocks。
不應使用hash clusters的情況:如果表不斷增長,并且重建新的、更大的hash cluster不可能的情況下,不應使用hash cluster;如果application經常使用full scans,并且要考慮為table的增大所必須預留的空間。
2)B-Tree indexes:
①使用B-Tree index的情況:當經常訪問表中的記錄占全表的不足5%時,應該考慮創建B-Tree index;如果在查詢時,indexes可以包含所有要訪問的字段,這個百分比可以更高些;或是對可以用于進行表的join時,也應考慮建立B- Tree index。
②indexes的增長方式:index總是平衡的,總是自下而上的增長。當rows被增加時,會添加到葉子節點的block上,如果葉子節點的 block被填滿,Oracle server會將該block split成兩個葉子blocks,每個保存50%的數據。因為新block的添加,葉子節點的父節點也需要添加相應的blocks索引值。如果父節點的 block被填滿,父節點也會被split成兩個節點,類似與剛才的子節點的split。這個過程會循環進行,直到b-tree保持平衡。index的層 次越多,其效率越低。此外,對于delete操作,會降低index的效率,特別是當有15%的rows被刪除,應該考慮rebuilding index。
③為了提高b-tree index的性能,應該定期對index進行rebuild。自9i,可以online創建、rebuild indexes,并且可以并行化進行。當index被rebuild時,相關的table仍然可以被訪問和進程DML操作。
ALTER INDEX i_name REBUILD ONLINE;
–ONLINE關鍵字表示在rebuild時,DML仍可進行。但是不允許并發的DML操作。
④壓縮索引:
在創建索引時使用下面的方法可以對index進程壓縮:
create index i_name on t_name(col1, col2) compress;
重建索引時可以使用:
alter index i_name rebuild compress;
壓縮索引不會多次存儲重復出現的關鍵字從而減少了存儲空間的需求。
對于非唯一索引的壓縮:Oracle存儲重復的關鍵字作為前綴在index block中,唯一的row id作為后綴存儲。
對于唯一索引的壓縮:也是類似的,將一致的前綴只保存一次,用于區分唯一性的部分會作為后綴存儲。但是這只適用于有多個字段組成的唯一索引,如果只有一個column的唯一索引沒有用于share的部分。
3)位圖(bitmap)索引:主要適用于distinct的values很少的字段,在其上建立索引。例如性別、工種等字段。但是對于有大量DML操作的表,bitmap index的性能不好,此情況應慎用。
① 適用bitmap index的情況:對于基數較低(low-cardinality)的column創建的索引;如果查詢語句中使用多個where條件,Oracle server可以使用邏輯的bit-and或bit-or操作來合并不同columns的bitmaps。
②性能的考慮:bitmap index占用空間較小,每個distinct key的存儲時以壓縮的方式,bitmap被分成不同的bitmap segments;對于low-cardinality字段非常快;很適合與規模大的只讀系統,如決策支持系統(DSS);但是對于DML操作性能比較 慢,不適用于OLTP應用,locking是加載在bitmap-segment上的,不是在記錄上的;bitmap index是存儲null值的,但b-tree不存儲;并發查詢、并發DML和并發的CREATE語句在bitmap indexes上是有效的。
③bitmap indexes的創建及管理:
create bitmap index i_name on t_name(col1) storage ( initial 200k next 200k pctincrease 0 maxextents 50) tablespace tsp_name;
對于每個DML操作之后,會對bitmap indexes進行相應的維護,所以對于每個DML操作,每個bitmap segment只會更新一次,既是該bitmap segment中不只一行更新數據。
4)反轉關鍵字索引(reverse key index):在創建索引時會將索引字段按bytes進行反轉(reverse)隨后將結果作為索引關鍵字。
①對于一個不斷增長的關鍵字,如由sequence產生的id,可以通過使用reverse key index避免索引的不斷split。但是對于常使用范圍查找的應用,只能使用全表掃描。
②創建reverse key index:
create index i_name on t_name(col1) reverse pctfree 30 storage( intial 200k next 200k pctincrease 0 maxextents 50) tablespace i_tspname;
或者
create index i_name on t_name(col1);
alter index i_name rebuild reverse;
5)組織索引表(IOT——index-organized table):類似與mysql中的innodb的存儲結構,具體結構如下圖:
適用于頻繁通過primary key或primary key的前綴訪問數據的情況。但是必須要求有primary key的限制。它加快了通過key查找數據的速度,并且從table和index整體上節省空間。
①在IOT中,沒有常規表中的那種物理上的row id的概念,而是引入了邏輯row id的概念,它是以變長的方式存儲的,其size要依靠primary key的值。
對于IOT中數據的訪問有兩種方法:
i)物理猜測guess,訪問時間等同于物理rowid的訪問時間
ii)當guess失敗,則通過primary key訪問IOT中的數據
(guess就是基于row所在的文件和block訪問,block的地址在表建立時是精確的,但是如果leaf block進行了拆分split是,就發生了改變。如果guess失敗,則通過primary key進行訪問。)這里沒太搞懂啊:(
②創建
CREATE TABLE countries
( country_id CHAR(2) CONSTRAINT country_id_nn NOT NULL,
country_name VARCHAR2(40),
currency_name VARCHAR2(25),
currency_symbol VARCHAR2(3),
map BLOB,
flag BLOB,
CONSTRAINT country_c_id_pk PRIMARY KEY (country_id))
ORGANIZATION INDEX
PCTTHRESHOLD 20
OVERFLOW TABLESPACE USERS;
影響IOT的行溢出的三個主要因素有:
** pctthreshold:此子句指明了在index block中容納一行數據可使用塊空間的百分比。如果one row數據超過基于此值計算的大小,所有的在including子句之后的字段將被移入overflow segment。如果overflow沒有被定義,則這種row溢出轉移將被拒絕。PCTTHRESHOLD默認值是50必須在0到50之間。
** including:后跟一個字段,如果數據行的長度超過了PCTTHRESHOLD指定的可用空間,從這個字段之后將數據行分為兩段,后面的部分放入溢出段中;
** overflow TABLESPACE :指明當index-organized表數據超出pctthreshold時,將部分columns放入data segment。
③IOT的字典視圖:
④使用mapping table
create table countries
( country_id char(2) constaint country_id_nn not null,
country_name varchar2(40),
currency_name varchar2(25),
currency_symbol varchar2(3),
constraint country_c_id_pk primary key (country_id))
organization index mapping table tablespace users;
當在索引組織表上創建位圖索引同heap table上創建bitmap是類似的,只是在組織索引表中的rowid對應的不是基礎表,而是相應的映射表(mapping table)。mapping table主要是維護一個邏輯row id(訪問組織索引表所需的)到physical row id(訪問位圖索引所需的)的映射。每個組織索引表會有一個mapping table,用于全表的映射。在heap organized base table中,用key訪問數據時,如果找到相應的key,bitmap記錄返回的是物理row id,可以用于基礎表的訪問。在組織索引表中,位圖索引也是用key進行搜索,當找到相應的key,bitmap返回的依然是物理row id,通過查詢mapping table,獲得相應的邏輯row id,再用于進入guess data block address或是用primary key訪問組織索引表
組織索引表中的row發生移動,不會使其上的bitmap indexes不可用,只是使mapping table中的相應邏輯row id不可用,但仍可通過primary key對其進行訪問。
對于mapping table的維護:
** 通過對IOT表進行analyze獲得mapping table的統計信息
** 查詢DBA_INDEXES視圖得知當前mapping table的精確度
SELECT INDEX_NAME, PCT_DIRECT_ACCESS FROM DBA_INDEXES WHERE PCT_DIRECT_ACCESS IS NOT NULL;
** 如果需要,使用alter table重建mapping table
alter table t_name mapping table update block references;
6)物化視圖(Materialized views)
物化視圖既存儲視圖的定義,又存儲視圖創建語句的查詢結果。可以將物化視圖定義的結果會產生一個實際的表,可以對其做類似normal table的定義,將其指派的某個表空間,對其添加索引,進行分區等。如果通過固化視圖就可以滿足的查詢,server會將查詢轉換為對物化視圖的查詢, 而不是對基礎表的查詢。這樣,部分代價昂貴的如join或統計的查詢就不必重復執行。
①創建:
create materialized view depart_sal_sum
tablespace data parallel (degree 4)
build immediate|deferred refresh fast
enable|disable query rewrite
as
select d.departmet_name, sum(e.salary) from departments d, employees e
where d.departmant_id=e.department_id group by d.department_name;
②refresh 物化視圖:具體有兩類:
i)完全的refresh:主要是通過truncate 當前的data,通過執行物化視圖的創建語句重新插入數據。
ii)fast refresh方法:它只會更新自上次refresh之后發生變化的數據。具體又有兩種:
** 使用materialized view logs:此方法中,所有關于視圖的基礎表的變化都會被捕獲并記錄到一個log中,將這些log data用于materialized view即可。
** 使用row id范圍:此方法需要一個直接裝在日志。記錄了需要被重新load的row id相關信息。materialized view就利用這些row id進行直接路徑的load。
一個視圖的定義使用force的refresh類型時,會盡可能的使用fast refresh方法,不得已才會使用complete refresh。默認情況是使用force refresh類型。如果使用never選項,則會抑制所有materialized view的refresh。
③自動refresh可以通過下面方法設置:
** 如果為materialized view設置oncommit選項,視圖會在base table每次commit操作后進行refresh。因為操作時異步的,所以不會讓user察覺到性能的降低。
** 在具體的時間點:可以使用START WITH和NEXT子句定義每次refresh的具體時間。為了實現此方法,必須將參數JOB_QUEUE_PROCESSES設置為大于0的值。
④可以用DBMS_MVIEW包進行手動的refresh。
** 對具體的某個materialized view進行refresh
DBMS_MVIEW.REFRESH(…)
** 對依賴某個基礎表的所有物化視圖進行refresh
DBMS_MVIEW.REFRESH_DEPENDENT(…)
** 對所有的materialized view進行refresh
DBMS_MVIEW.REFRESH_ALL_MVIEWS;
為了執行手動refresh job,必須為其設置適當的JOB_QUEUE_PROCESSES和JOB_QUEUE_INTERVAL參數。
⑤物化視圖的查詢重寫(query rewrite):這一過程是通過優化器(optimizer)完成的,對于應用而言是透明的。可以加速對基礎表的部分訪問。user不需要被明確的賦予 materialized view的權限,只要其有base table的權限,則其發出的相關查詢就可以被重寫為對物化視圖的訪問。materialized view也可設置為enable和disable。
進行query rewrite,必須使QUERY_REWRITE_ENABLED設置為true。對于使用query rewrite的user必須有GLOBAL QUERY REWRITE或QUERY REWRITE的權限。后者只允許user對自己schema下面的materialized view進行query rewrite,前者除此還可對其他有權限的schema進行query rewrite。
⑥物化視圖在帶來效率的同時也會增加占用的額外空間,并且需要refresh的開支。對此在DBMS_OLAP包的sumary advisor可以用于對代價與收益的比較從而輔助覺得materialized view的創建。
vii)對query rewrit的控制分為三個層次:
** 在初始化參數級別上:
OPTIMIZER_MODE:查詢重寫只有在cost-based優化模式下才能進行。可在session級別動態設置;
QUERY_REWRITE_ENABLED:可設置為true或是false,可在session級別動態設置;
QUERY_REWRITE_INTEGRITY:可設置為ENFORCED(默認值,只有server能確保一致性時——物化視圖是最新的并且 query rewrite使用了有效的驗證約束的情況下才進行query rewrite)、TRUSTED(物化視圖是最新的,此外相信RELY的約束, 就算這個約束沒有Enabled和Validated)、 STALE_TOLERATED(query rewrite允許使用沒有及時refresh的物化視圖)。此參數也是可以在session級別上動態設置的。
** 在sql中使用hints——REWRITE和NOREWRITE,它可以覆蓋在創建或alter物化視圖是設置的enable query rewrite子句。
** dimensions(這個也沒太懂~~~~(>_<)~~~~ )
viii)可以使用dbms_mview包中的EXPLAIN_MVIEW和explain_rewrite對materialized view和query rewrite進行解釋。
3、OLTP系統:
主要特點是:集中的insert和update操作,數據不斷增長,多事務并發進行。要求高可用性、高速、高度并發、降低恢復時間。
1)空間分配:避免動態的空間分配,應該為tables、cluster、indexes明確指明占用的tablespace。此外通過觀察數據增長的規律,設計extent每次分配的大小。
2)indexes:在DB中indexes的創建和維護都是占用一定開支的,所以,索引的創建必須嚴謹,每個索引的存在必須是實際需要的;在外鍵上建立 索引有助于在子表數據被修改時不會locking父表中的數據;b-tree索引在OLTP中優于位圖索引,因為locking對DML的影響(當DML 操作發生時b-tree索引中只是鎖某些rows,但bitmap索引,會locking整個有相同key的rows);可以考慮使用reverse index來解決b-tree中sequence columns的問題;應該定期對indexes進行rebuild。
3)hash clustering:使用hash clusters可以提高等值查詢的訪問速度。但是對于下面的情況則不適用它:
** 大量insert操作
** 存在大量用更大的columns values對表進行update的操作,因為會引起數據的遷移。
如果表不斷增長,可能在hash key上存在大量沖突,從而是部分數據存放在overflow blocks中,為了避免這種情況,正確的評估hashkeys的值。給hash key更大的number,有助于解決沖突。
4)OLTP Application Issues:
* 對于完整性約束,應該使用DB中聲明的constraints代替application中code的邏輯限制。這里主要考慮的是參照完整性和約束的check。
* 應該考慮使用Oracle中的共享code對象,如packages、procedures和Functions。
* 應該盡可能使用綁定變量
* 定義恰當的cursor_sharing參數,有助于user共享解析代碼。可設置的值有:
EXACT:默認值,只在精確匹配的情況下共享cursors
SIMILAR:如果SQL語句是字面量,則只有當已有的執行計劃是最佳時才使用它,如果已有執行計劃不是最佳則重新對這個SQL語句進行分析來制定最佳執行計劃。
FORCE:如果SQL語句是字面量,則迫使Optimizer始終使用已有的執行計劃,無論已有的執行計劃是不是最佳的。
4、決策支持系統(DSS/Data Warehouses)
DSS的特點是該application會提取相應的有用數組成容易理解的報表。將OLTP中的數據進行提取、整合、匯總。使用大量的全表掃描。決策者根 據相關的結果做下一步的決策。它需要有快速的響應時間,并且數據應該確保精確。并發查詢的特點就是為了data warehouse環境設計的。
1)存儲的分配:
* 謹慎的考慮block size和DB_FILE_MULTIBLOCK_READ_COUNT參數的設置。可以考慮適當增大block_size、DB_FILE_MULTIBLOCK_READ_COUNT。
* 確保extent的size是block_size的整數倍。
* 定期執行analyze或是dbms_stats進行表的statistics。
2)indexing:因為大量的查詢是通過全表掃描完成的,所以應盡量減少index占用的空間和對其維護帶來的開銷。
* 可以的話,可以考慮不使用索引,只保留那些需要用于進行篩選查詢的index;
* 定期的用不一致的分布數據產生直方圖。
* 考慮使用bitmap indexes
* 對于需要快速用關鍵字查詢的data可將相應的表建為IOT。
* 考慮使用index和hash cluster,特別是hash cluster。但不要在定期批量增長的表上建立cluster。
3)application issues:
在data warehouse中,sql的解析時間并不重要,所以可以適當的減小library cache的大小。應該更關注執行計劃:盡量使用并發查詢。Symmetric multiprocessors (SMP), clustered, or massively parallel processing (MPP)將能很好的提高性能。SQL的調節優化很重要。
有時可以棄用綁定變量,因為:當analyze后產生直方圖,可以用于一定的查詢優化,但是這種優化只使用在不使用綁定變量的情況。如果使用綁定變量,則optimizer就不會使用直方圖了。對此要小心設置cursor_sharing參數的值。
5、混合系統(Hybrid System)
posted on 2010-01-12 12:32 gdufo 閱讀(615) 評論(0) 編輯 收藏 所屬分類: Database (oracle, sqlser,MYSQL)