1.
選
用適合的
ORACLE
優
化器
???? ORACLE
的
優
化器共有
3
種
???? A 、 RULE ( 基于 規則 ) b 、 COST ( 基于成本 ) c 、 CHOOSE ( 選擇 性 )
???? 設 置缺省的 優 化器,可以通 過對 init.ora 文件中 OPTIMIZER_MODE 參數的各 種 聲明,如 RULE , COST , CHOOSE , ALL_ROWS , FIRST_ROWS 。 你當然也在 SQL 句 級 或是會 話 (session) 級對 其 進 行覆蓋。
???? 為 了使用基于成本的 優 化器 (CBO , Cost-Based Optimizer) , 你必 須經 常運行 analyze 命令,以增加數據 庫 中的 對 象 統計 信息 (object statistics) 的準確性。
???? 如果數據 庫 的 優 化器模式 設 置 為選擇 性 (CHOOSE) ,那 么實際 的 優 化器模式將和是否運行 過 analyze 命令有 關 。 如果 table 已 經 被 analyze 過 , 優 化器模式將自 動 成 為 CBO , 反之,數據 庫 將采用 RULE 形式的 優 化器。
在缺省情況下, ORACLE 采用 CHOOSE 優 化器, 為 了避免那些不必要的全表 掃 描 (full table scan) , 你必 須 盡量避免使用 CHOOSE 優 化器,而直接采用基于 規則 或者基于成本的 優 化器。
2.
訪問
Table
的方式
???? ORACLE
采用兩
種訪問
表中
記錄
的方式:
???? A 、 全表 掃 描
????????? 全表 掃 描就是 順 序地 訪問 表中 每 條 記錄 。 ORACLE 采用一次 讀 入多個數據 塊 (database block) 的方式 優 化全表 掃 描。
???? B 、 通 過 ROWID 訪問 表
????????? 你可以采用基于 ROWID 的 訪問 方式情況,提高 訪問 表的效率, ROWID 包含了表中 記錄 的物理位置信息。 ORACLE 采用索引 (INDEX) 實現 了數據和存放數據的物理位置 (ROWID) 之 間 的 聯 系。通常索引提供了快速 訪問 ROWID 的方法,因此那些基于索引列的 查詢 就可以得到性 能上的提高。
3.
共享
SQL
語
句
????
為
了不重
復
解析相同的
SQL
語
句,在第一次解析之后,
ORACLE
將
SQL
語
句存放在內存中。
這塊
位于系
統
全局區域
SGA(system global area)
的共享池
(shared buffer pool)
中的內存可以被所有的數據
庫
用
戶
共享。
因此,當你
執
行一個
SQL
語
句
(
有
時
被稱
為
一個游
標
)
時
,如果它和之前的
執
行
過
的
語
句完全相同,
ORACLE
就能很快
獲
得已
經
被解析的
語
句以及最好的
執
行路徑。
ORACLE
的
這
個功能大大地提高了
SQL
的
執
行性能并
節
省了內存的使用。
???? 可惜的是 ORACLE 只 對簡單 的表提供高速 緩 沖 (cache buffering) , 這 個功能并不適用于多表 連 接 查詢 。
???? 數據 庫 管理 員 必 須 在 init.ora 中 為這 個區域 設 置合適的參數,當 這 個內存區域越大,就可以保留更多的 語 句,當然被共享的可能性也就越大了。
???? 當你向 ORACLE 提交一個 SQL 語 句, ORACLE 會首先在 這塊 內存中 查 找相同的 語 句。 這 里需要注明的是, ORACLE 對 兩者采取的是一 種嚴 格匹配,要達成共享, SQL 語 句必 須 完全相同 ( 包括空格, 換 行等 ) 。
???? 數據 庫 管理 員 必 須 在 init.ora 中 為這 個區域 設 置合適的參數,當 這 個內存區域越大,就可以保留更多的 語 句,當然被共享的可能性也就越大了。
???? 共享的 語 句必 須滿 足三個條件:
???? A 、 字符 級 的比 較 : 當前被 執 行的 語 句和共享池中的 語 句必 須 完全相同。
???? B 、 兩個 語 句所指的 對 象必 須 完全相同:
???? C 、 兩個 SQL 語 句中必 須 使用相同的名字的 綁 定 變 量 (bind variables) 。
4.
選擇
最有效率的表名
順
序
(
只在基于
規則
的
優
化器中有效
)
???? ORACLE
的解析器按照從右到左的
順
序
處
理
FROM
子句中的表名,因此
FROM
子句中寫在最后的表
(
基
礎
表
driving table)
將被最先
處
理。在
FROM
子句中包含多個表的情況下,你必
須選擇記錄
條數最少的表作
為
基
礎
表。當
ORACLE
處
理多個表
時
,
會運用排序及合并的方式
連
接它
們
。首先,
掃
描第一個表
(FROM
子句中最后的那個表
)
并
對記錄進
行派序,然后
掃
描第二個表
(FROM
子句中最后第二個表
)
,最后將所有從第二個表中
檢
索出的
記錄
與第一個表中合適
記錄進
行合并。
???? 如果有 3 個以上的表 連 接 查詢 , 那就需要 選擇 交叉表 (intersection table) 作 為 基 礎 表, 交叉表是指那個被其他表所引用的表。
5.WHERE
子句中的
連
接
順
序
???? ORACLE
采用自下而上的
順
序解析
WHERE
子句,根據
這
個原理,表之
間
的
連
接必
須
寫在其他
WHERE
條件之前,
那些可以
過濾
掉最大數量
記錄
的條件必
須
寫在
WHERE
子句的末尾。
6.SELECT
子句中避免使用
' * '
????
當你想在
SELECT
子句中列出所有的
COLUMN
時
,使用
動態
SQL
列引用
'*'
是一個方便的方法。不幸的是,
這
是一個非常低效的方法。
實際
上,
ORACLE
在解析的
過
程中,
會將
'*'
依次
轉換
成所有的列名,
這
個工作是通
過查詢
數據字典完成的,
這
意味著將耗
費
更多的
時間
。
7.
減少
訪問
數據
庫
的次數
????
當
執
行
每
條
SQL
語
句
時
,
ORACLE
在內部
執
行了
許
多工作:解析
SQL
語
句,估算索引的利用率,
綁
定
變
量,
讀
數據
塊
等等。由此可
見
,減少
訪問
數據
庫
的次數,就能
實際
上減少
ORACLE
的工作量。
8.
使用
DECODE
函數來減少
處
理
時間
????
使用
DECODE
函數可以避免重
復掃
描相同
記錄
或重
復連
接相同的表。
9.
整合
簡單
,無
關聯
的數據
庫訪問
????
如果你有幾個
簡單
的數據
庫查詢語
句,你可以把它
們
整合到一個
查詢
中
(
即使它
們
之
間
沒有
關
系
)
10.
刪
除重
復記錄
11.
用
TRUNCATE
替代
DELETE
????
當
刪
除表中的
記錄時
,在通常情況下,
回
滾
段
(rollback segments )
用來存放可以被恢
復
的信息。
如果你沒有
COMMIT
事
務
,
ORACLE
會將數據恢
復
到
刪
除之前的狀
態
(
準確地
說
是恢
復
到
執
行
刪
除命令之前的狀況
)
。
???? 而當運用 TRUNCATE 時 , 回 滾 段不再存放任何可被恢 復 的信息。當命令運行后,數據不能被恢 復 。因此很少的 資 源被 調 用, 執 行 時間 也會很短。
12.
盡量多使用
COMMIT
????
只要有可能,在程序中盡量多使用
COMMIT
,
這樣
程序的性能得到提高,需求也會因
為
COMMIT
所
釋
放的
資
源而減少
???? COMMIT 所 釋 放的 資 源:
???? A 、 回 滾 段上用于恢 復 數據的信息。
???? B 、被程序 語 句 獲 得的 鎖 。
???? C 、 redo log buffer 中的空 間 。
???? D 、 ORACLE 為 管理上述 3 種資 源中的內部花 費 。
13.
計
算
記錄
條數
????
和一般的
觀
點相反,
count(*)
比
count(1)
稍快,當然如果可以通
過
索引
檢
索,
對
索引列的
計
數仍舊是最快的。例如
COUNT(EMPNO)
14.
用
Where
子句替
換
HAVING
子句
????
避免使用
HAVING
子句,
HAVING
只會在
檢
索出所有
記錄
之后才
對結
果集
進
行
過濾
。
這
個
處
理需要排序,
總計
等操作。如果能通
過
WHERE
子句限制
記錄
的數目,那就能減少
這
方面的
開銷
。
15.
減少
對
表的
查詢
????
在含有子
查詢
的
SQL
語
句中,要特
別
注意減少
對
表的
查詢
。
16.
通
過
內部函數提高
SQL
效率。
17.
使用表的
別
名
(Alias)
????
當在
SQL
語
句中
連
接多個表
時
,
請
使用表的
別
名并把
別
名前
綴
于
每
個
Column
上。
這樣
一來,就可以減少解析的
時間
并減少那些由
Column
歧
義
引起的
語
法
錯誤
。
18.
用
EXISTS
替代
IN
????
在
許
多基于基
礎
表的
查詢
中,
為
了
滿
足一個條件,往往需要
對
另一個表
進
行
聯
接。在
這種
情況下,使用
EXISTS(
或
NOT EXISTS)
通常將提高
查詢
的效率。
19.
用
NOT EXISTS
替代
NOT IN
????
在子
查詢
中,
NOT IN
子句將
執
行一個內部的排序和合并。
無
論
在哪
種
情況下,
NOT IN
都是最低效的
(
因
為
它
對
子
查詢
中的表
執
行了一個全表遍
歷
)
。
為
了避免使用
NOT IN
,我
們
可以把它改寫成外
連
接
(Outer Joins)
或
NOT EXISTS
。
20.
用表
連
接替
換
EXISTS
????
通常來
說
,
采用表
連
接的方式比
EXISTS
更有效率
21.
用
EXISTS
替
換
DISTINCT
????
當提交一個包含一
對
多表信息
(
比如部
門
表和雇
員
表
)
的
查詢時
,避免在
SELECT
子句中使用
DISTINCT
。
一般可以考
慮
用
EXIST
替
換
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
