数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

优化数据库大幅度提高Oracle的性能


发布日期:2019年04月08日
 
优化数据库大幅度提高Oracle的性能

几个简单的步骤大幅提高Oracle性能我优化数据库的三板斧

数据库优化的讨论可以说是一个永恆的主题资深的Oracle优化人员通常会要求提出性能问题的人对数据库做一个statspack贴出数据库配置等等还有的人认为要抓出执行最慢的语句来进行优化但实际情况是提出疑问的人很可能根本不懂执行计划更不要说statspack了而我认为数据库优化应该首先从大的方面考虑网络服务器硬件配置操作系统配置Oracle服务器配置数据结构组织然后才是具体的调整实际上网络硬件等往往无法决定更换应用程序一般也无法修改因此应该着重从数据库配置数据结构上来下手首先让数据库有一个良好的配置然后再考虑具体优化某些过慢的语句我在给我的用户系统进行优化的过程中总结了一些基本的简单易行的办法来优化数据库算是我的三板斧呵呵不过请注意这些不一定普遍使用甚至有的会有副作用但是对OLTP系统基于成本的数据库往往行之有效不妨试试(注附件是Burleson写的用来报告数据库性能等信息的脚本本文用到)

一.设置合适的SGA

常常有人抱怨服务器硬件很好但是Oracle就是很慢很可能是内存分配不合理造成的()假设内存有M这通常是小型应用建议Oracle的SGA大约M其中共享池(SHARED_POOL_SIZE)可以设置M到M根据实际的用户数查询等来定数据块缓沖区可以大致分配MMi下需要设置DB_BLOCK_BUFFERSDB_BLOCK_BUFFER*DB_BLOCK_SIZE等于数据块缓沖区大小i 下的数据缓沖区可以用db_cache_size来直接分配

()假设内存有GOracle 的SGA可以考虑分配M共享池分配M到M数据缓沖区分配M到M

()内存GSGA可以考虑分配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\utlxplansql来创建PLAN_TABLE这个表)

SQL> SET AUTOTRACE ONSQL>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_tablessql;SQL> select analyze table ||owner||||table_name|| compute statistics; from dba_tables where owner=GAXZUSR;SQL> spool offSQL> spool spool d:\analyze_indexessql;SQL> select analyze index ||owner||||index_name|| compute statistics; from dba_indexes where owner=GAXZUSR;SQL> spool offSQL> @d:\analyze_tablessqlSQL> @d:\analyze_indexessql

解释上面的语句生成了两个sql文件分别分析全部的GAXZUSR的表和索引如果需要按照百分比来分析表可以修改一下脚本通过上面的步骤我们就完成了对表和索引的分析可以测试一下速度的改进啦建议定期运行上面的语句尤其是数据经过大量更新

当然也可以通过dbms_stats来分析表和索引更方便一些但是我仍然习惯上面的方法因为成功与否会直接提示出来

另外我们可以将优化模式进行修改optimizer_mode值可以是RULECHOOSEFIRST_ROWS和ALL_ROWS对于OLTP系统可以改成FIRST_ROWS来要求查询尽快返回结果这样即使不用分析在一般情况下也可以提高查询性能但是表和索引经过分析后有助于找到最合适的执行计划

三.设置cursor_sharing=FORCE 或SIMILAR

这种方法是i才开始有的oracle不支持通过设置该参数可以强制共享只有文字不同的语句解释计划例如下面两条语句可以共享

SQL> SELECT * FROM MYTABLE WHERE NAME=tomSQL> SELECT * FROM MYTABLE WHERE NAME=turner

这个方法可以大幅降低缓沖区利用率低的问题避免语句重新解释通过这个功能可以很大程度上解决硬解析带来的性能下降的问题个人感觉可根据系统的实际情况决定是否将该参数改成FORCE该参数默认是exact不过一定要注意修改之前必须先给ORACLE打补丁否则改之后oracle会占用%的CPU无法使用对于ORACLEi可以设置成SIMILAR这个设置综合了FORCE和EXACT的优点不过请慎用这个功能这个参数也可能带来很大的负面影响!

四.将常用的小表索引钉在数据缓存KEEP池中

内存上数据读取速度远远比硬盘中读取要快据称内存中数据读的速度是硬盘的倍!如果资源比较丰富把常用的小的而且经常进行全表扫描的表给钉内存中当然是在好不过了可以简单的通过ALTER TABLE tablename CACHE来实现在ORACLEi之后可以使用ALTER TABLE table STORAGE(BUFFER_POOL KEEP)一般来说可以考虑把数据块之内的表放在keep池中当然要根据内存大小等因素来定关于如何查出那些表或索引符合条件可以使用本文提供的accesssql和access_reportsql这两个脚本是着名的Oracle专家 Burleson写的你也可以在读懂了情况下根据实际情况调整一下脚本对于索引可以通过ALTER INDEX indexname STORAGE(BUFFER_POOL KEEP)来钉在KEEP池中

将表定在KEEP池中需要做一些准备工作对于ORACLEi 需要设置DB_KEEP_CACHE_SIZE对于i需要设置buffer_pool_keepi中还要修改db_block_lru_latches该参数默认是无法使用buffer_pool_keep该参数应该比**CPU数量少但是要大于才能设置DB_KEEP_CACHE_BUFFERbuffer_pool_keep从db_block_buffers中分配因此也要小于db_block_buffers设置好这些参数后就可以把常用对象永久钉在内存里

五.设置optimizer_max_permutations

对于多表连接查询如果采用基于成本优化(CBO)ORACLE会计算出很多种运行方案

从中选择出最优方案这个参数就是设置oracle究竟从多少种方案来选择最优如果设置太大那么计算最优方案过程也是时间比较长的Oraclei默认是建议改成对于i已经默认是

六.调整排序参数

() SORT_AREA_SIZE:默认的用来排序的SORT_AREA_SIZE大小是K通常显得有点小一般可以考虑设置成M(这个参数不能设置过大因为每个连接都要分配同样的排序内存

() SORT_MULTIBLOCK_READ_COUNT:增大这个参数可以提高临时表空间排序性能该参数默认是可以改成来对比一下排序查询时间变化注意这个参数的最大值与平台有关系

上一篇:ORACLE常用数据字典的查询视图

下一篇:Oracle10g的SQL正则表达式