檢查 1: 建立 Index Key --------------------------------------------------------------------------------
大多數的查詢速度慢, 利用新增 Index Key, 效率上大都會有一定地提升.
INDEX 過多將影響 UPDATE INSERT
即使使用DISABLE 也是增加維護複雜度 請使用必要的INDEX 特例
另外BY CASE 處理--------------------------------------------------------------------------------
檢查 2: Where 條件中, 是否用函數 --------------------------------------------------------------------------------
Where 條件的欄位若使用函數, 會讓建立在欄位的 Index Key 無法使用, 如: nvl, decode, trunc, to_char, ... 等, 儘量避免在欄位上使用, 如 nvl( col, 'Y' ) = 'Y' 可改用 (col = 'Y' or col is null).檢查 3: Where 條件中, 是否使用 In / Not In / Exists --------------------------------------------------------------------------------
使用 In / Not In / Exists, 有可能會使查詢所需的 Cost 增加, 若真要使用, 這三種方式可用 explain 進行偵測, 看目前 SQL 在哪一種方式較好.
檢查 4: Where 條件中, 是否使用 Outer Join --------------------------------------------------------------------------------
使用 Outer Join, 會導致查詢所需的 Cost 增加, 解決方式: 分成兩個 SELECT, 一個 SELECT 用 Join, 一個 SELECT 用 IS NOT NULL, 然後用 Union or Union All 加起來.
(曾經有查詢 3 分多鐘, 在改成 Union All 之後, 查詢不到 10 秒鐘)
另一種方式, 就是將 Outer Join 的 Table, 做為 Subquery 當作 Columns 使用.
(這方式有時效能反而更差,需與 Outer Join 方式, 測試比較看看)
--------------------------------------------------------------------------------
檢查 5: Where 條件中, 是否比較不同的資料型態 --------------------------------------------------------------------------------
這個有可能在速度上會差異很多, 如: charCol = numCol 改用 charCol = to_char(numCol)
如果是日期切記不要用TO_CHAR 或是SUBSTR 去做轉換--------------------------------------------------------------------------------
檢查 6: Where 條件中, 若使用變數, 可能讓建立在欄位的 Index Key 無法使用 --------------------------------------------------------------------------------一般來說, 是不會發生這種情形, 但萬一遇到了, 解決方式為: 接收到實際值後, 將變數轉換成實際值, 然後再執行之.
詳細資訊, 請見 Oracle Metalink
http://metalink.oracle.com/metalink/plsql/tar_main.this_tar?tar_num=5363227.993&p_ctryCode=840.
--------------------------------------------------------------------------------
檢查 7: 是否使用 Distinct / Order By --------------------------------------------------------------------------------
使用 Distinct / Order By 會使查詢所需的 Cost 增加, 若可以不用, 盡量少用之.檢查 8: 是否使用 View 有些情況可能會影響速度 --------------------------------------------------------------------------------
如 View 關聯了 7 個 Table, 但實際需求只要關聯 2 個 Table 的欄位資料, 多餘的 5 個 Table 關聯, 只會影響查詢速度.檢查 9: 一個 Select 的效能 > 多個 Select 的效能 --------------------------------------------------------------------------------
解決方式: 將多個 Select 改用 Union or Union All or Subquery.檢查 10: 多個 TABLE 同時關聯 --------------------------------------------------------------------------------
多個 TABLE 同時關聯, 造成查詢速度太慢, 解決方式: 可以先將一個過濾資料 Table 作成 Subquery, 然後再將 Subquery 與其他 Table 關聯.
(曾經有查詢 6 分多鐘, 在改成 Subquery 之後, 查詢不到 1 分秒鐘)
可以用WITH VIEW方式將資料LOAD 到記憶體
--------------------------------------------------------------------------------
檢查 11: 查詢條件的增加 or 取回資料的範圍縮小 --------------------------------------------------------------------------------用意當然在於減少取回的資料量, 減少 Database Buffer 的使用量.
--------------------------------------------------------------------------------
檢查 12: 資料量的增加 --------------------------------------------------------------------------------這個我想, 每個人都知道的, 資料量一直不斷地增加, 導致查詢速度越來越慢, 解決方式: 減少資料量的取回 or 將資料搬到歷史檔.
--------------------------------------------------------------------------------
檢查 13: 將常查詢但很費時的資料, 建立 Materialized View or Summary Table --------------------------------------------------------------------------------利用晚上較沒人使用的時間, 將查詢要很久時間的資料, 收集起來, 就可快速查詢.
--------------------------------------------------------------------------------
檢查 14: 將不常用的 Inactive Data, 放在其他 Tablespace or Database 中 --------------------------------------------------------------------------------
這種做法, 目的就是減少空間, 增加存取效能.檢查 15: 建立 Partition Table --------------------------------------------------------------------------------
這種做法, 就是區隔資料, 把它想像成 Index 就容易理解了.
但是管理 需要人為介入 要看是否有大到那個程度--------------------------------------------------------------------------------
檢查 16: 若 Select 是採用 Rule Base, 考慮 From Table 順序 / Where 條件順序 --------------------------------------------------------------------------------
若 Select 是採用 Rule Base, 則擺放在 from / where 的位置,就會影響查詢速度.
檢查 17: 在 Select 之後 /*+ ... */ --------------------------------------------------------------------------------
有時 Oracle 分析 Select 語句後, 判斷有誤而採用錯誤的方式, 如該用 Index 卻沒使用, 這時就自力自強吧, 而常用的有 :
/*+ INDEX (tableName indexName) */
/*+ RULE */
/*+ CHOOSE */
/*+ FIRST_ROWS */
/*+ ALL_ROWS */
/*+ INDEX_SS_DESC*/
如: Select /*+ RULE */ colName1, colName2, ... from ...
--------------------------------------------------------------------------------
檢查 18: Explain Plan --------------------------------------------------------------------------------
參考 Oracle 提供的 Explain Plan 分析 SQL 的執行路徑, 看哪種 SQL 寫法 Cost 時間較少.
注意: 有時 Cost 少不代表實際查詢速度快
不過還是可以參考 建議可以先 ANALYSIS
只是看一下要用那種HINT 解決 依照經驗
--------------------------------------------------------------------------------
檢查 19: 資料被 Locked --------------------------------------------------------------------------------CHECK 被哪些TABLE LOCKED--------------------------------------------------------------------------------
檢查 20: 資料量不多, 但卻查詢要很久的時間 --------------------------------------------------------------------------------此 Table 常做新增 / 刪除動作, 導致雖然資料量不多, 但資料分散太大,
解決方式: 重建 Table.
檢查 21: 增加 Temporary Tablespace or SGA 的空間大小 --------------------------------------------------------------------------------
找DBA
--------------------------------------------------------------------------------
檢查 22: 改變程式邏輯 --------------------------------------------------------------------------------BY CASE
REF: http://tomkuo139.blogspot.com/2009/08/oracle-select-sql-tuning.html
1樓. Rex2012/06/07 17:09感謝您的分享
謝謝你的分享,讓我學到不少



