幾個簡單的步驟大幅提高Oracle性能
我優化數據庫的三板斧
數據庫優化的討論可以說是一個永恆的主題
資深的Oracle優化人員通常會要求提出性能問題的人對數據庫做一個statspack
貼出數據庫配置等等
還有的人認為要抓出執行最慢的語句來進行優化
但實際情況是
提出疑問的人很可能根本不懂執行計劃
更不要說statspack了
而我認為
數據庫優化
應該首先從大的方面考慮
網絡
服務器硬件配置
操作系統配置
Oracle服務器配置
數據結構組織
然後才是具體的調整
實際上網絡
硬件等往往無法決定更換
應用程序一般也無法修改
因此應該著重從數據庫配置
數據結構上來下手
首先讓數據庫有一個良好的配置
然後再考慮具體優化某些過慢的語句
我在給我的用戶系統進行優化的過程中
總結了一些基本的
簡單易行的辦法來優化數據庫
算是我的三板斧
呵呵
不過請注意
這些不一定普遍使用
甚至有的會有副作用
但是對OLTP系統
基於成本的數據庫往往行之有效
不妨試試
(注
附件是Burleson寫的用來報告數據庫性能等信息的腳本
本文用到)
一.設置合適的SGA 常常有人抱怨服務器硬件很好
但是Oracle就是很慢
很可能是內存分配不合理造成的
(
)假設內存有
M
這通常是小型應用
建議Oracle的SGA大約
M
其中
共享池(SHARED_POOL_SIZE)可以設置
M到
M
根據實際的用戶數
查詢等來定
數據塊緩沖區可以大致分配
M
M
i下需要設置DB_BLOCK_BUFFERS
DB_BLOCK_BUFFER*DB_BLOCK_SIZE等於數據塊緩沖區大小
i 下的數據緩沖區可以用db_cache_size來直接分配
(
)假設內存有
G
Oracle 的SGA可以考慮分配
M
共享池分配
M到
M
數據緩沖區分配
M到
M
(
)內存
G
SGA可以考慮分配
G
共享池
M到
M
剩下的給數據塊緩沖區
(
)內存
G以上
共享池
M到
M就足夠啦
再多也沒有太大幫助
(Biti_rainy有專述)數據緩沖區是盡可能的大
但是一定要注意兩個問題
一是要給操作系統和其他應用留夠內存
二是對於
位的操作系統
Oracle的SGA有
G的限制
有的
位操作系統上可以突破這個限制
方法還請看Biti的大作吧
二.分析表和索引更改優化模式 Oracle默認優化模式是CHOOSE
在這種情況下
如果表沒有經過分析
經常導致查詢使用全表掃描
而不使用索引
這通常導致磁盤I/O太多
而導致查詢很慢
如果沒有使用執行計劃穩定性
則應該把表和索引都分析一下
這樣可能直接會使查詢速度大幅提升
分析表命令可以用ANALYZE TABLE 分析索引可以用ANALYZE INDEX命令
對於少於
萬的表
可以考慮分析整個表
對於很大的表
可以按百分比來分析
但是百分比不能過低
否則生成的統計信息可能不准確
可以通過DBA_TABLES的LAST_ANALYZED列來查看表是否經過分析或分析時間
索引可以通過DBA_INDEXES的LAST_ANALYZED列
下面通過例子來說明分析前後的速度對比
(表CASE_GA_AJZLZ大約有
萬數據
有主鍵)首先在SQLPLUS中打開自動查詢執行計劃功能
(第一次要執行\RDBMS\ADMIN\utlxplan
sql來創建PLAN_TABLE這個表)
SQL> SET AUTOTRACE ON
SQL>SET TIMING ON
通過SET AUTOTRACE ON 來查看語句的執行計劃
通過SET TIMING ON 來查看語句運行時間
SQL> select count(*) from CASE_GA_AJZLZ;
COUNT(*)
已用時間:
:
:
Execution Plan
SELECT STATEMENT Optimizer=CHOOSE
SORT (AGGREGATE)
TABLE ACCESS (FULL) OF
CASE_GA_AJZLZ
……………………
請注意上面分析中的TABLE ACCESS(FULL)
這說明該語句執行了全表掃描
而且查詢使用了
秒
這時表還沒有經過分析
下面我們來對該表進行分析
SQL> analyze table CASE_GA_AJZLZ compute statistics;
表已分析
已用時間:
:
:
然後再來查詢
SQL> select count(*) from CASE_GA_AJZLZ;
COUNT(*)
已用時間:
:
:
Execution Plan
SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=
Card=
)
SORT (AGGREGATE)
INDEX (FAST FULL SCAN) OF
PK_AJZLZ
(UNIQUE) (Cost=
Card=
)
…………………………
請注意
這次時間僅僅用了
秒!這要歸功於INDEX(FAST FULL SCAN)
通過分析表
查詢使用了PK_AJZLZ索引
磁盤I/O大幅減少
速度也大幅提升!下面的實用語句可以用來生成分析某個用戶的所有表和索引
假設用戶是GAXZUSR
SQL> set pagesize
SQL> spool d:\analyze_tables
sql;
SQL> select
analyze table
||owner||
||table_name||
compute statistics;
from dba_tables where owner=
GAXZUSR
;
SQL> spool off
SQL> spool spool d:\analyze_indexes
sql;
SQL> select
analyze index
||owner||
||index_name||
compute statistics;
from dba_indexes where owner=
GAXZUSR
;
SQL> spool off
SQL> @d:\analyze_tables
sql
SQL> @d:\analyze_indexes
sql
解釋
上面的語句生成了兩個sql文件
分別分析全部的GAXZUSR的表和索引
如果需要按照百分比來分析表
可以修改一下腳本
通過上面的步驟
我們就完成了對表和索引的分析
可以測試一下速度的改進啦
建議定期運行上面的語句
尤其是數據經過大量更新
當然
也可以通過dbms_stats來分析表和索引
更方便一些
但是我仍然習慣上面的方法
因為成功與否會直接提示出來
另外
我們可以將優化模式進行修改
optimizer_mode值可以是RULE
CHOOSE
FIRST_ROWS和ALL_ROWS
對於OLTP系統
可以改成FIRST_ROWS
來要求查詢盡快返回結果
這樣即使不用分析
在一般情況下也可以提高查詢性能
但是表和索引經過分析後有助於找到最合適的執行計劃
三.設置cursor_sharing=FORCE 或SIMILAR 這種方法是
i才開始有的
oracle
不支持
通過設置該參數
可以強制共享只有文字不同的語句解釋計劃
例如下面兩條語句可以共享
SQL> SELECT * FROM MYTABLE WHERE NAME=
tom
SQL> SELECT * FROM MYTABLE WHERE NAME=
turner
這個方法可以大幅降低緩沖區利用率低的問題
避免語句重新解釋
通過這個功能
可以很大程度上解決硬解析帶來的性能下降的問題
個人感覺可根據系統的實際情況
決定是否將該參數改成FORCE
該參數默認是exact
不過一定要注意
修改之前
必須先給ORACLE打補丁
否則改之後oracle會占用
%的CPU
無法使用
對於ORACLE
i
可以設置成SIMILAR
這個設置綜合了FORCE和EXACT的優點
不過請慎用這個功能
這個參數也可能帶來很大的負面影響!
四.將常用的小表索引釘在數據緩存KEEP池中 內存上數據讀取速度遠遠比硬盤中讀取要快
據稱
內存中數據讀的速度是硬盤的
倍!如果資源比較豐富
把常用的小的
而且經常進行全表掃描的表給釘內存中
當然是在好不過了
可以簡單的通過ALTER TABLE tablename CACHE來實現
在ORACLE
i之後可以使用ALTER TABLE table STORAGE(BUFFER_POOL KEEP)
一般來說
可以考慮把
數據塊之內的表放在keep池中
當然要根據內存大小等因素來定
關於如何查出那些表或索引符合條件
可以使用本文提供的access
sql和access_report
sql
這兩個腳本是著名的Oracle專家 Burleson寫的
你也可以在讀懂了情況下根據實際情況調整一下腳本
對於索引
可以通過ALTER INDEX indexname STORAGE(BUFFER_POOL KEEP)來釘在KEEP池中
將表定在KEEP池中需要做一些准備工作
對於ORACLE
i 需要設置DB_KEEP_CACHE_SIZE
對於
i
需要設置buffer_pool_keep
在
i中
還要修改db_block_lru_latches
該參數默認是
無法使用buffer_pool_keep
該參數應該比
*
*CPU數量少
但是要大於
才能設置DB_KEEP_CACHE_BUFFER
buffer_pool_keep從db_block_buffers中分配
因此也要小於db_block_buffers
設置好這些參數後
就可以把常用對象永久釘在內存裡
五.設置optimizer_max_permutations 對於多表連接查詢
如果采用基於成本優化(CBO)
ORACLE會計算出很多種運行方案
從中選擇出最優方案
這個參數就是設置oracle究竟從多少種方案來選擇最優
如果設置太大
那麼計算最優方案過程也是時間比較長的
Oracle
和
i默認是
建議改成
對於
i
已經默認是
了
六.調整排序參數 (
) SORT_AREA_SIZE:默認的用來排序的SORT_AREA_SIZE大小是
K
通常顯得有點小
一般可以考慮設置成
M(
)
這個參數不能設置過大
因為每個連接都要分配同樣的排序內存
(
) SORT_MULTIBLOCK_READ_COUNT:增大這個參數可以提高臨時表空間排序性能
該參數默認是
可以改成
來對比一下排序查詢時間變化
注意
這個參數的最大值與平台有關系
七.調整其它幾個關鍵的性能參數 很多人認為使用oracle數據庫
系統的默認參數就是最好的
其實不是這樣
From:http://tw.wingwit.com/Article/program/Oracle/201311/16704.html