如何利用oracle第三方工具做数据库的性能优化

吃可爱长大的小学妹 提交于 2019-12-02 16:26:57

经常看到很多人费好大力气写好了SQL,但是执行效率很慢。一提到性能优化就挠头,四处寻求帮助。

其实如果了解哪些方面会影响oracle性能的话,这并不是一件难事。如果能够借助到第三方工具的帮助,那么性能优化简直就是傻瓜式的。

今天就誓将教会你如何利用object browser的功能来优化数据库性能。



  • 一、Oracle统计信息的调整

一个运行良好的数据库,常常面临着数据量的增加而性能逐步恶化的困扰,性能问题通常被认为是由于磁盘容量或者内存等的规格引起的,

但实际上是由于SQL处理,也就是“实行计划”没有被正确编写引起的。

实行计划就是执行SQL时,数据库内部是怎样处理SQL的。

例如,是否使用索引,多张表存在的时候使用什么顺序结合等。

起初编写的实行计划并不一定是最好的。例如附加的索引没有被使用到。

记录的行数很少时,使用全面搜索更快一些,但如果使用索引,性能的问题就产生了。

那么,怎么才能正确的做成实行计划呢?

虽然有SQL的修正和追加索引等手段,但在这之前最重要的是“取得最新的统计信息”。

统计信息是记录各表的记录行数和数据分布的信息。

由于实行计划是基于统计信息决定的,随着数据的增加,性能下降,取得记录数等最新的统计信息,使实行计划最正确,提高性能。

使用SI Object Browser更新统计信息参照以下方法。

1.对象列表中,在表显示的状态下按“Ctrl+A”,选中所有表。(也可以选中处理较慢的SQL所参照的表。)

2.表被选中的状态下点击鼠标右键,选择“统计信息”。

3.统计信息画面显示出来,选中“修正正确的信息”,点击“OK”。



现在只支持Oracle版本,“在对象列表中表示详细信息”可以使详细信息在对象列表中显示。

选择“工具”菜单-->“选项”选项卡。

“对象列表”-->“表示对象固有的详细信息”设置成ON。  


“表示”菜单-->“表示更新”。

这个设置有使表的记录数列表显示的优势。 


统计信息的更新并不是对应用进行修正,更新统计信息之后还不能解决问题的话,建议使用SQL优化等其

他手段。我们接下来就讲一下SQL的优化。


  • 二、SQL优化
性能恶化的原因多数是因为SQL,这次要说明怎样使SQL最优化。
SQL最优化就是“使内存得到最有效的利用”。

在数据库中有叫“程序库缓存”和“数据库缓冲”的内存区域,这些内存主要用于缓存。

把数据的读取作为例子,由于数据存储在硬盘的数据文件中,想要读取数据必须要有权限访问硬盘。
但是,读取硬盘上的文件需要时间,在数据库访问硬盘的时候,内存也在拷贝同样的数据,在第二次之后,只从内存就可以读取数据,提高了处理速度。这种结构就叫做缓存。

但是,第二次以后并不一定能使用缓存。由于内存大小是有限制的,当容量过大时则不能登录内存。或者缓存的数据将按照由旧到新的顺序被删除。

也就是说性能恶化的原因多数是由于数据增加,导致从访问内存转换到访问硬盘。活用内存缓存,使处理速度恢复到从前,这就是性能优化。

具体方法有增加内存,改变初始化参数等,也可以修改SQL文改善缓存。以下介绍两种方法。


使用提示句

不使用索引读取数据时(全表搜索),如果需要很大的内存导致不能访问缓存中的数据,缓存的功能就无效了。 
上回说到,“取得最新的统计信息”方法可以使实行计划得到改善,如果在SQL文中追加以下的提示句也许会更好。

SELECT /*+ INDEX (表名索引名)*/列名 FROM 表名
在SELECT的后面加上“/*+ INDEX (表名索引名)*/”。这样就可以明确的命令数据库“要使用索引”。

SI Object Browser中使用“实行计划”或者是“索引顾问”功能可以查询索引是否被使用,或者性能有多大的改善。
这里特殊说一下,很多DBA最喜欢着眼于这个实行计划和索引INDEX。
如果你看到下面这个界面,是不是觉得不用麻烦别人了?

在执行一条SQL之后,系统提示你已经创建了哪些INDEX,而且其中哪些使用了,哪些没使用。
系统同时提示你还需要创建哪些INDEX,而且不需要你手动创建,下面的[创建]按钮一下搞定。
想知道创建之后有没有效果?点一下[测试]按钮就OK。


使用绑定变量

执行SQL时,数据库内部为了作成SQL实行计划必须要进行SQL解析,这样就会消耗CPU资源。
通常,SQL如果和过去实行过的SQL一样的话,通过程序库缓存就可以直接使用以前的解析结果。
例如,「SELECT * FROM SCOTT.EMP WHERE EMPNO = 1」和「SELECT * FROM SCOTT.EMP WHERE EMPNO = 2」是不同的SQL,则不能使用缓存功能。

不把SELECT语句的WHERE条件和INSERT语句插入的各项目的值设置成固定值,而是像「SELECT * FROM SCOTT.EMP WHERE EMPNO = :EMPNO」这样把值的部分设置成变量。
这个变量就是绑定变量。
使用绑定变量,因为SQL问变成了一样的,所以可以使用缓存功能。
绑定变量还可以从存储过程,应用发行SQL。以下的代码是以C#为例子,也支持除此之外的主要的程序语言。

//向Order表插入数据
SqlCommand cm = new SqlCommand(sql, cn);
stringsql = "INSERT INTO ORDER(";
sql += "OrderNo,";
sql += "CustomerNo,";
sql += "Price)";
sql += "VALUES ";
sql += "( @OrderNo ,";
sql += "@CustomerNo,";
sql += "@Price)";
cm.CommandText = sql;

//设置各绑定变量的值
cm.Parameters.Add(new SqlParameter("OrderNo", lblOrderNo.Text));
cm.Parameters.Add(new SqlParameter("CustomerNo", lblCustomerNo.ToString()));
cm.Parameters.Add(new SqlParameter("ShippingCharge", lblPrice.Text));
//实行SQL
cm.ExecuteNonQuery();

即使是这样还不能改善性能时,要考虑减轻访问硬盘的负荷,增加内存等方法。
首先要最优化比较容易的SQL。
接下来我们再讲一下其他导致性能恶化的原因以及优化方法。


  • 三、让原因具体化
上面说性能恶化的原因多数是因为SQL。接下来将要说明如果修正SQL还不能解决问题的话,使用其他的解决办法。

在Oracle中,发生等待时间原因的事件名和等待时间存在于字典视图中,调查下面的字典视图可以得到原因。

・V$SYSTEM_EVENT…显示数据库启动后发生的待机事件
・V$SESSION_EVENT…显示现行的session中全部的待机事件
・V$SESSION_WAIT…显示session正在待机中还是待机完了之后的事件

例如想要通过V$SYSTEM_EVENT调查时,使用以下的SQL文。
========================================================
SELECT EVENT, WAIT_CLASS, TOTAL_WAITS, AVERAGE_WAIT  
FROM V$SYSTEM_EVENT
WHERE WAIT_CLASS ! = 'Idle'
========================================================

WAIT_CLASS列是'Idle'事件时,也就是空闲时间(等待用户请求的时间),不能作为性能恶化的原因,所以在WHERE中要除去'Idle'。

实行上述SQL后,EVENT列中表示事件名,TOTAL_WAITS列中表示总待机时间,AVERAGE_WAIT列中表示平均待机时间,这之中时间长的事件名就是性能恶化的原因。

下记是具有代表性的待机事件和解决方法。
1. db file scattered read/db file sequential read
通过全表搜索,索引搜索读取时发生。
【对策】改善SQL实行计划。

2. direct path write/direct path write temp
磁盘排序处理时花费的等待时间。
【对策】内存有效排序。

3.在“Library”中开始待机事件(log buffer space等)
与程序库缓冲关联的待机事件。
在载入工程的时间和多进程等同时访问时发生。
【对策】减少程序库缓存错误

4.在“log buffer”中开始待机事件(log buffer space等)
与日志文件关联的待机事件。Check point和写入慢时发生。
【对策】增加日志文件大小,增加日志文件组。

各种事件的详细内容请参照oracle以下讲解:
http://otndnld.oracle.co.jp/document/products/oracle11g/111/doc_dvd/server.111/E05771-04/waitevents.htm#12032
在V$SYSTEM_EVENT视图中记录了数据库从启动开始到现在的待机事件,有可能不能确定最近的性能恶化的原因。
这时,使用V$SESSION_EVENT视图,比较现象发生前和发生后的差别,就能得到确切的原因。
性能恶化刚刚发生的话,也可以使用V$SESSION_WAIT。

这就是几乎全部有关oracle性能优化的基础了。
性能优化看起来比较难,但是掌握了关键点的话谁都能操作。
非常希望能给大家带来帮助,如果有问题欢迎随时交流!
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!