Oracle資料庫開發指南(二)

chenmolin發表於2004-11-15

分析:注意所使用的時間的不同只要簡單地改變所給出的統計的次序,第二個查詢比第一個查詢快了14 秒,那麼可以設想一下當查詢的結構設計不好的時候耗用幾個小時的情形。

注:在SQL*Plus中可設定TIMINGON(預設為OFF),這樣對於每條SQl語句,將會返回Oracle執行該語句所用的時間。

2.7 更新大量的資料

當更新大量的資料的時候可能會出現資料庫效能的變差,特別是在業務高峰期間,我們建議在非業務期間進行,對於特別大量的更新,建議使用效能上的調優技術(這裡可能包括刪除索引,直接插入等調整技術),或者由我們DBA來規劃進行。這裡所說的更新包括:插入,更新,刪除。

[@more@]

2.8 經常性的COMMIT

COMMIT可以將事務中所作的任何改變寫到實際的表中,但是在後臺它做的工作不只如此,資料庫中,有一個區域是用以儲存全部的寫到實際表中之前的事務資料的,ORACLE將這一區域叫做ROLLBACK段,當你執行一個COMMIT命令以後,與你的SQL相關聯的事務會將ROLLBACK段中的內容寫到實際的表中,然後更新這一區域,ROLLBAKC段中的原有內容就被刪除了,ROLLBACK命令是另一種清除ROLLBACK段的命令方法,只是它不將所做的改動寫到目標表中。

COMMIT所釋放的資源:

l         回滾段上用於恢復資料的資訊

l         被程式語句獲得的鎖

l         redo log buffer 中的空間

l         ORACLE為管理上述3種資源中的內部花費

如你所料,如果你一直不執行COMMITROLLBACK命令那麼事務就會一直儲存在ROLLBACK段中,隨之而來的是如果你要裝入的資料大小比ROLLBACK段的可用空間還要大,資料庫將會終止並掛起所有的活動事務,不執行COMMIT命令是通用程式的一個缺陷,有規律地使用COMMIT命令將會使資料庫系統輸入的效能穩定。

  經常我們會收到快照太舊和資源被佔用等等的錯誤,這都是沒有經常性的COMMIT造成的,所以建議大家在完成一定數量的更新後能夠及時COMMIT

2.9 儲存過程

如果所使用的查詢有規律可循,那麼你可以試著使用過程,過程可以呼叫很大的一組SQL 的語句,過程是被資料庫的引擎編譯後執行的,與SQL語句不同,資料庫引擎在執行過程的時候不需要進行最佳化,過程相對於獨立的多個SQL語句它對於使用者來說更容易使用,而對於資料庫來說更為有效。

2.10 避免使用OR

如果可能的話,應該在查詢儘量避免使用邏輯運算子OROR會不可避免的根據表的大小降低查詢的速度。我們發現IN通常比OR要快。雖然最佳化器的文件中並不是這樣說的。

2.11 SELECT子句中避免使用‘*

當你想在SELECT子句中列出所有的COLUMN時,使用動態SQL列引用‘*’是一個方便的方法。不幸的是,這是一個非常低效的方法。實際上,ORACLE在解析的過程中,會將‘*’依次轉換成所有的列名,這個工作是透過查詢資料字典完成的,這意味著將耗費更多的時間。

2.12 減少訪問資料庫的次數

當執行每條SQL語句時,ORACLE在內部執行了許多工作:解析SQL語句,估算索引的利用率,繫結變數讀資料塊等等。由此可見,減少訪問資料庫的次數,就能實際上減少ORACLE的工作量。

例如,

以下有三種方法可以檢索出僱員號等於03420291的職員。

方法1 (最低效)
    SELECT EMP_NAME , SALARY , GRADE
    FROM EMP 
    WHERE EMP_NO = 342;
    SELECT EMP_NAME , SALARY , GRADE
    FROM EMP 
    WHERE EMP_NO = 291;

方法2 (次低效)
    DECLARE 
       CURSOR C1 (E_NO NUMBER) IS 
      SELECT EMP_NAME,SALARY,GRADE 

FROM EMP 
WHERE EMP_NO = E_NO;

BEGIN 
       OPEN C1(342);
       FETCH C1 INTO …,..,.. ;
       OPEN C1(291);
       FETCH C1 INTO …,..,.. ;
       CLOSE C1;
    END;

方法3 (高效)
    SELECT A.EMP_NAME , A.SALARY , A.GRADE,
           B.EMP_NAME , B.SALARY , B.GRADE
    FROM EMP A, EMP B
    WHERE A.EMP_NO = 342
    AND   B.EMP_NO = 291;

2.13 避免在索引列上使用計算

WHERE子句中,如果索引列是函式的一部分.最佳化器將不使用索引而使用全表掃描。

舉例:

低效:

SELECT …

FROM DEPT

WHERE SAL * 12 > 25000;

高效:

SELECT …

FROM DEPT

WHERE SAL  > 25000/12;

2.14 避免在索引列上使用IS NULLIS NOT NULL

避免在索引中使用任何可以為空的列,ORACLE將無法使用該索引。對於單列索引,如果列包含空值,索引中將不存在此記錄。 對於複合索引,如果每個列都為空,索引中同樣不存在此記錄。如果至少有一個列不為空,則記錄存在於索引中。

 

 

 

 

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/41224/viewspace-780726/,如需轉載,請註明出處,否則將追究法律責任。

相關文章