Oracle優化器模式與Oracle索引優化規則_第1頁
Oracle優化器模式與Oracle索引優化規則_第2頁
Oracle優化器模式與Oracle索引優化規則_第3頁
Oracle優化器模式與Oracle索引優化規則_第4頁
Oracle優化器模式與Oracle索引優化規則_第5頁
已閱讀5頁,還剩34頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、Oracle 優化器介紹.Oracle索引介紹.SQL優化規則介紹.索引優化規則介紹.Oracle優化器模式優化器模式:Oracle在執行一個SQL之前,首先要分析一下語句的執行計劃,然后再按執行計劃去執行。分析語句的執行計劃的工作是由優化器(Optimizer) 來完成的 .Oracle優化器(Optimizer)是Oracle在執行SQL之前分析語句的工具.Oracle的優化器有兩種優化方式:基于規則的優化方式(Rule-Based Optimization,簡稱為RBO)和基于代價的優化方式(Cost-Based Optimization,簡稱為CBO). RBO方式優化器在分析SQL語

2、句時,所遵循的是Oracle內部預定的一些規則。比如我們常見的,當一個where子句中的一列有索引時去走索引. CBO方式CBO是看語句的代價,這里的代價主要指Cpu和內存。優化器在判斷是否用這種方式時,主要參照的是表及索引的統計信息。統計信息給出表的大小 、有少行、每行的長度等信息。這些統計信息起初在庫內是沒有的,是你在做analyze后才出現的.在Oracle8及以后的版本,Oracle列推薦用CBO的方式。優化器的優化模式(Optermizer Mode) :包括Rule,Choose,First rows,All rows這四種方式.Rule:不用多說,即走基于規則的方式。 rboCh

3、oose:指的是當一個表或或索引有統計信息,則走CBO的方式,如果表或索引沒統計信息,表又不是特別的小,而且相應的列有索引時,那么就走索引,走RBO的方式。First Rows:它與Choose方式是類似的,所不同的是當一個表有統計信息時,它將是以最快的方式返回查詢的最先的幾行,從總體上減少了響應時間。對于排序分頁頁顯示這種查詢尤其適用.All Rows:也就是我們所說的Cost的方式,當一個表有統計信息時,它將以最快的方式返回表的所有的行,從總體上提高查詢的吞吐量。沒有統計信息則走基于規則的方式 .查看缺省的Oracle優化器:SQLshow parameters optimizer_mod

4、e;可以在init文件中對整個instance的所有會話設置.也可以單獨對某個會話設置: SQLALTER SESSION SET optimizer_mode= FIRST_ROWS; 查看統計信息: 1.select tt.table_name,tt.num_rows,tt.blocks,tt.empty_blocks,tt.avg_row_len from dba_tables tt where tt.owner=SCOTT;2.select ttt.index_name,ttt.num_rows,ttt.distinct_keys,ttt.avg_leaf_blocks_per_key

5、,ttt.clustering_factor from dba_indexes ttt where ttt.owner=SCOTT;人工進行統計:對某一個用戶下的所有表和索引執行統計分析:execute dbms_stats.gather_schema_stats(ownname =SCOTT,cascade=true); 對單個表執行統計分析:EXECUTE dbms_stats.gather_table_stats (ownname=SCOTT, tabname=EMP,estimate_percent=50,cascade=true). 從Oracle Database 10g開始,Or

6、acle在建庫后就默認創建了一個名為GATHER_STATS_JOB的定時任務,用于自動收集CBO的統計信息,調用DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC收集統計信息.默認情況下在工作日晚上10:00-6:00和周末全天開啟.一起運行的還有另外一個Job:AUTO_SPACE_ADVISOR_JOB .可以通過以下查詢這個JOB的運行情況: select * from Dba_Scheduler_Jobs where JOB_NAME =GATHER_STATS_JOB .關閉自動統計功能:SQL exec BMS_SCHEDULER.DISABLE(

7、GATHER_STATS_JOB); Oracle 索引介紹Oracle索引簡介索引是建立在表的一列或多個列上的輔助對象,目的是加快訪問表中的數據(加快查詢); 索引由根節點、分支節點和葉子節點組成,上級索引塊包含下級索引塊的索引數據,葉節點包含索引數據和確定行實際位置的rowid。查詢DBA_INDEXES視圖可得到表中所有索引的列表,注意只能通過USER_INDEXES的方法來檢索模式(schema)的索引。訪問USER_IND_COLUMNS視圖可得到一個給定表中被索引的特定列。 通過每個行的ROWID,索引Oracle提供了訪問單行數據的能力。ROWID其實就是直接指向單獨行的線路圖。

8、 索引分類索引分類l邏輯上: 單列索引, 多列索引, 唯一索引,非惟一索引。l物理上: B*-Tree索引,反向索引,位圖索引。單列索引和復合索引單列索引和復合索引l單列索引是基于單個列所建立的索引。多列索引是基于兩列或多列所建立的索引。l單列索引 Create index emp_ind1 on emp(ename);l復合索引 Create index emp_ind2 on emp(ename,job); 惟一索引和非惟一索引惟一索引和非惟一索引l惟一索引是索引列值不能重復的索引。l非惟一索引是索引列值可以重復的索引。無論是惟一索引還是非惟一索引,索引列都允許NULL。B*-tree索引

9、索引lB*Tree索引是最常見的索引結構,默認建立的索引就是這種類型的索引。B*Tree索引在檢索高基數數據列(高基數數據列是指該列有很多不同的值)時提供了最好的性能。當取出的行數占總行數比例較小時B-Tree索引比全表檢索提供了更有效的方法。但當檢查的范圍超過表的10%時就不能提高取回數據的性能。B-Tree索引是基于二叉樹的,由分支塊(branch block)和葉塊(leaf block)組成。在樹結構中,位于最底層底塊被稱為葉塊,包含每個被索引列的值和行所對應的rowid。在葉節點的上面是分支塊,用來導航結構,包含了索引列(關鍵字)范圍和另一索引塊的地址 .l 創建索引: 1: cre

10、ate index STUDENT_IND_name on STUDENT(NAME) tablespace USERS ; 2:create index STUDENT_IND_name on STUDENT(NAME,AGE) tablespace USERS ;B*-tree索引索引B*-tree索引索引l假設我們要找索引中值為80的行,從索引樹的最上層入口開始,定位到大于等于50,然后往左找,找到第2個分支塊,定位為75100,最后再定位到葉塊上,找到80所對應的rowid,然后根據rowid去讀取數據塊獲取數據。如果查詢條件是范圍選擇的,比如where column 20 and c

11、olumn value,因為在索引的葉塊中索引碼沒有分類,所以不能通過搜索相鄰葉塊完成區域掃描。注意:只有索引中的值是逆向的,表中的值保持不變。位圖索引位圖索引l位圖索引主要用于決策支持系統或靜態數據,不支持行級鎖定。位圖索引最好用于低cardinality列(即列的唯一值除以行數為一個很小的值,接近零),例如又一個“性別”列,列值有“Male”,“Female”,“Null”等3種,但一共有300萬條記錄,那么3/3000000約等于0,這種情況下最適合用位圖索引。l 創建位圖索引: create bitmap index inx_bitmap_emp on emp(sex);位圖索引的格式

12、位圖索引的格式 l行值 1 2 3 4 5 6 7 8 9 10 Male 1 0 0 0 0 0 0 0 1 1 Female 0 1 1 1 0 0 1 1 0 0 Null 0 0 0 0 1 1 0 0 0 0 位圖索引位圖索引l如果搜索where gender=Male,要統計性別是”Male”的列行數的話,Oracle很快就能從位圖中找到共3行即第1,9,10行是符合條件的;如果要搜索where gender=Male or gender=Female的列的行數的話,也很容易從位圖中找到共8行即1,2,3,4,7,8,9,10行是符合條件的。如果要搜索表的值的話,那么Oracle會

13、用內部的轉換函數將位圖中的相關信息轉換成rowid來訪問數據塊。 聚簇聚簇l聚簇是根據碼值找到數據的物理存儲位置,從而達到快速檢索數據的目的。聚簇索引的順序就是數據的物理存儲順序,葉節點就是數據節點。非聚簇索引的順序與數據物理排列順序無關,葉節點仍然是索引節點,只不過有一個指針指向對應的數據塊。一個表最多只能有一個聚簇索引。 使用使用 Oracle 聚簇索引聚簇索引 l在Oracle當中,聚簇不是索引的組織形式,而是表的組織形式。多用于表之間的連接字段。 例:dept(deptno, dnma,e loc) 和表 emp(empno, ename, job, mgr, . deptno), 常

14、在deptno上進行連接,可以針對deptno字段建立聚簇,然后建立基于該聚簇的索引,并讓兩個表都使用上該聚簇。 Oracle 聚簇索引聚簇索引lCREATE CLUSTER lpersonnel( department_number NUMBER(2) )l SIZE 512 STORAGE (INITIAL 100K NEXT 50K); l CREATE TABLE emp (l empno NUMBER l PRIMARY KEY,l ename VARCHAR2(10) NOT NULL l CHECK (ename = UPPER(ename),l job VARCHAR2(9),

15、 l mgr NUMBER ,l comm NUMBER(9,0) DEFAULT NULL, l deptno NUMBER(2) NOT NULL )l CLUSTER personnel (deptno);l l CREATE TABLE dept (l deptno NUMBER(2),l dname VARCHAR2(9),l loc VARCHAR2(9)l CLUSTER personnel (deptno);l l CREATE INDEX idx_personnel ON CLUSTER personnel; Oracle 聚簇索引聚簇索引l這樣可以讓兩個表同時用上聚簇索引。

16、保證兩個表的記錄按照depno值盡量存放到同一個物理塊當中。 使用索引的一些規則使用索引的一些規則1.索引對大表最有用,不要在小表上加索引.2.為每個表中的主碼指定一個唯一索引。3.索引對于那些頻繁出現在SQL命令中的where子句中的列最有用,不管這些列在選擇中用來限定行還是為了表連接。4.當一個屬性中存在很多不同的值時,可以使用索引。Oracle建議當一個屬性中有少于30個不同值時,索引不是很有用,當屬性中有100或更多不同值時索引就很明顯地有用了。相似地,只有當使用索引進行查詢的結果不超過文件中所有記錄總數的20%時,使用索引才有幫助。5.檢查你的DBMS對索引的限制,即便要在每個表允許

17、的索引個數上。許多系統不超過16個索引而且限制每個索引鍵值的大小。對一個表創建的索引數一般不超過5個.7. 對于包含空值的屬性建立索引時要小心,在很多DBMS里有空值的行不能在索引中作為參照。8. 時常需要做刪除、更新、插入操作的表不要創建索引.9. 將表和索引建立在不同的表空間內(TABLESPACES). 不要將不屬于ORACLE內部系統的對象存放到SYSTEM表空間里. 同時,確保數據表空間和索引表空間置于不同的硬盤上.減少I/O競爭.SQL優化的一些規則:( 有些規則只有在基于規則的優化器里有效).1選擇最有效率的表名順序:選擇最有效率的表名順序:1.把記錄少的表放在from子句的最后

18、面一個表.2.如果有3個以上的表連接查詢, 那就需要選擇交叉表(intersection table)作為基礎表, 交叉表是指那個被其他表所引用的表.原因:ORACLE的解析器按照從右到左的順序處理FROM子句中的表名,因此FROM子句中寫在最后的表(基礎表 driving table)將被最先處理. 在FROM子句中包含多個表的情況下,你必須選擇記錄條數最少的表作為基礎表.當ORACLE處理多個表時, 會運用排序及合并的方式連接它們.首先,掃描第一個表(FROM子句中最后的那個表)并對記錄進行排序,然后掃描第二個表(FROM子句中最后第二個表),最后將所有從第二個表中檢索出的記錄與第一個表中

19、合適記錄進行合并. 2 WHERE子句中的連接順序 : ORACLE采用自右向左的順序解析WHERE子句, 那些可以過濾掉最大數量記錄的條件必須寫在WHERE子句的末尾. 3.SELECT子句中避免使用 * ORACLE在解析的過程中, 需要通過查詢數據字典將* 依次轉換成所有的列名.4. 使用表的別名(Alias) 當在SQL語句中連接多個表時, 請使用表的別名并把別名前綴于每個Column上.這樣一來,就可以減少解析的時間并減少那些由Column歧義引起的語法錯誤. (Column歧義指的是由于SQL中不同的表具有相同的Column名,當SQL語句中出現這個Column時,SQL解析器無法

20、判斷這個Column的歸屬) 5.減少訪問數據庫的次數: 當執行每條SQL語句時, ORACLE在內部執行了許多工作: 解析SQL語句, 估算索引的利用率, 綁定變量 , 讀數據塊等等. 由此可見, 減少訪問數據庫的次數 , 就能實際上減少ORACLE的工作量.6.(可能的話)用TRUNCATE替代DELETE. 當刪除表中的記錄時,在通常情況下, 回滾段(rollback segments ) 用來存放可以被恢復的信息. 如果你沒有COMMIT事務,ORACLE會將數據恢復到執行刪除命令之前的狀況. 而當運用TRUNCATE時, 回滾段不再存放任何可被恢復的信息.當命令運行后,數據不能被恢復

21、.因此很少的資源被調用,執行時間也會很短. (TRUNCATE只在刪除全表里的記錄時適用,TRUNCATE是DDL不是DML) 7. (可能的話)使用COMMIT 只要有可能,在程序中盡量多使用COMMIT, 這樣程序的性能得到提高,需求也會因為COMMIT所釋放的資源而減少: COMMIT所釋放的資源: a. 回滾段上用于恢復數據的信息. b. 被程序語句獲得的鎖 c. redo log buffer 中的空間 d. ORACLE為管理上述3種資源中的內部花費 8.(可能的話)用Where子句替換HAVING子句 盡量少使用HAVING子句, HAVING 只會在檢索出所有記錄之后才對結果集

22、進行過濾. 這個處理需要排序,總計等操作. 如果能通過WHERE子句限制記錄的數目,那就能減少這方面的開銷. 9.(某些情況下)可以用EXISTS替代IN . NOT EXISTS替代NOT IN 性能比較: 1.Select * from t1 where x in ( select y from t2) 2.select * from t1 where exists ( select 1 from t2 where t2. y = t1.x ) 當t1記錄比較少,t2比較大時適合用exists(exists大部分情況會利用到index),當子查詢記錄集很小時用in比較合適. 原因分析: 1

23、.Select * from T1 where x in ( select y from T2 ) 執行的過程相當于: select * from t1, ( select distinct y from t2 ) t3 where t1.x = t3.y; 2. select * from t1 where exists ( select 1 from t2 where t2.y = t1.x )執行的過程相當于:for x in ( select * from t1 ) loop if ( exists ( select 1 from t2 where t2.y = t1.x ) then

24、 OUTPUT THE RECORD end ifend loop這樣表 T1 要被完全掃描一遍 . 所以可以得出結論:當t1記錄比較少,t2比較大時適合用exists(exists大部分情況會利用到index),當子查詢記錄集很小時用in比較合適.10.用表連接替換EXISTS改進第9打優化規則的例子.11.用EXISTS替換DISTINCT EXISTS 使查詢更為迅速,因為RDBMS核心模塊在子查詢的條件一旦滿足后 立刻返回結果. DISTINCT會先進行排序,然后會根據排序后的順序去除相同的行.12.使用顯式的游標(CURSOR) 使用隱式的游標,將會執行兩次操作. 第一次檢索記錄,

25、第二次檢查TOO MANY ROWS 這個exception . 而顯式游標不執行第二次操作. 11-例: 1.(低效)SELECT DISTINCT DEPT_NO,DEPT_NAME FROM DEPT D,EMP E WHERE D.DEPT_NO = E.DEPT_NO ;2.高效: SELECT DEPT_NO,DEPT_NAME FROM DEPT D WHERE EXISTS ( SELECT * FROM EMP E WHERE E.DEPT_NO = D.DEPT_NO); l13.用索引提高效率 通常,通過索引查詢數據比全表掃描要快. 當ORACLE找出執行查詢和Updat

26、e語句的最佳路徑時, ORACLE優化器將使用索引. 除了那些LONG或LONG RAW數據類型, 你可以索引幾乎所有的列. 在大型表中使用索引特別有效. 雖然使用索引能得到查詢效率的提高,但是我們也必須注意到它的代價. 索引需要空間來 存儲,也需要定期維護, 每當有記錄在表中增減或索引列被修改時, 索引本身也會被修改. 這意味著每條記錄的INSERT , DELETE , UPDATE將為此多付出4 , 5 次的磁盤I/O . 因為索引需要額外的存儲空間和處理,那些不必要的索引反而會使查詢反應時間變慢. 定期的重構索引是有必要的. ALTER INDEX REBUILD Oracle索引優化

27、規則索引優化規則:1. like件中不要以通配符(WILDCARD)開始,否則索引將不被采用. 例:SELECT LODGING FROM LODGING WHERE MANAGER LIKE HANMAN; 2.避免在索引列上使用計算或改變索引列的類型或使用!=及 例: SELECT FROM DEPT WHERE SAL * 12 25000; SELECT FROM EMP WHERE EMP_TYPE=to_char(123); select . Where ACCOUNT_NAME|ACCOUNT_TYPE=AMEXA; select where empno!=8888 ;3.避免在

28、索引列上使用NOT .4.用=替代 . 高效: SELECT * FROM EMP WHERE DEPTNO =4 低效: SELECT * FROM EMP WHERE DEPTNO 3 兩者的區別在于, 前者DBMS將直接跳到第一個DEPT等于4的記錄而后者將首先定位到DEPTNO=3的記錄并且向前掃描到第一個DEPT大于3的記錄. l5.用UNION替換OR (適用于索引列) l通常情況下, 用UNION替換WHERE子句中的OR將會起到較好的效果. 對索引列使用OR將造成全表掃描. 注意, 以上規則只針對多個索引列有效. 如果有column沒有被索引, 查詢效率可能會因為你沒有選擇OR而降低. 在下面的例子中, LOC_ID 和REGION上都建有索引. 高效: SELECT LOC_ID , LOC_DESC , REGION FROM LOCATION WHERE LOC_ID = 10 UNION SELECT LOC_ID , LOC_DESC , REGION

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論