前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >90-最近优化过的几套Oracle数据库回顾

90-最近优化过的几套Oracle数据库回顾

作者头像
老虎刘
发布2022-06-22 18:31:10
2840
发布2022-06-22 18:31:10
举报

最近给几个比较重要的客户优化了几套Oracle数据库, 套用一句名言: 性能好的数据库都是相似的, 性能差的数据库各有各的"不幸". 实际上性能好的数据库基本看不到,除非是一些负载非常小的库. 绝大部分数据库都是处于亚健康状态, 很多拿来做优化的库, 要么是濒临瘫痪,要么是业务用户实在是忍无可忍.

对优化不了解的用户, 遇到性能问题很多时候最先想到的处理方法不是优化, 而是更换硬件, 更有甚者干脆再开发一套新的应用.

今天介绍的这几个案例, 就是让大家多了解优化, 每一套"不幸"的数据库, 经过优化之后, 基本上都能够得到新生.

客户1:

数据库升级到12.2版本后, 共享内存(shared pool)一段时间后就增大到了100多G, 而buffer cache被挤压到只剩500多M, 导致SQL执行效率非常低. 客户之前找过专家改过几个隐含参数(如_cursor_obsolete_threshold / _memory_imm_mode_without_autosga等), 还是没有解决:

经过分析AWR发现, 这是一个ges resource dynamic相关的bug, 根据MOS提供的workaround做了调整, 这一步做到了治标. 其实oracle的bug一般不会轻易踩到, 这个bug就是因为应用的一些SQL没有使用绑定变量;还有一些insert values过多的绑定变量, 而绑定变量的长度变化较大, 生成了大量的子游标; 再有就是insert 后面的select 语句是由上千个union 组成, 这些都是诱发bug的原因, 这些问题都需要开发修改代码, 才能从根本上解决问题. 如果把这些问题都解决了, 这个bug应该也就不会出现.

几乎每个数据库都存在一些索引和SQL写法的问题,这个库也不例外,主要问题通过参数调整先临时解决了. 然后把TOP SQL涉及的表增加一些索引, 同时还发现一些SQL的写法需要改进. 索引和SQL写法在两大类性能问题几乎在所有的数据库都存在, 索引可以补建, SQL写法的问题只能通过改代码解决,oracle的优化器虽然很强大, 但是也不能随心所欲, 很多开发写的SQL实现业务逻辑没问题, 性能就惨不忍睹了.

加了索引之后, 这个库的性能又得到了较大的提升. 治本的SQL写法问题还需要开发对代码做调整.

客户2:

这是一个数据仓库, 里面有很多几百G大表, 而且还在持续不断增长. 每天大量的全表扫描(一天的读取量大概是70T), 还好有oracle的一体机Exadata强大的硬件做支撑. 如果不是Oracle原厂的一体机Exadata的硬件, 很难支撑这样的业务系统. Exadata强大的pmem(硬件-持久化内存)和offload(软件), 可以让100多G大表的全表扫描, 只需要1秒左右, 真香.

即便是强大的硬件做支撑, 遇到统计信息收集不准或是参数设置不当的情况, 也是7~8个小时也跑不出结果. 还有在大表中做delete的时候, 即使是一个不删除任何记录的SQL, 也需要执行几十分钟. 而且随着数据量的不断增长, 每天的业务加载时间的持续增长也在意料之中.

这个库的优化手段说起来比较简单, 就是对大表做分区 , 找出合适的字段, 使用合理的分区类型, 不但能实现几百倍的性能提升, 而且不会随着数据量的增长而增加业务加载时间. 分区是数据仓库最有效的的优化方法, 没有之一. 除了分区裁剪可以大幅减少IO读取, 分区还是compress/in-memory等技术的"最佳搭档". 在很多开源数据库, 经常听到一个名词叫"分表", 这是因为分区技术不太成熟; 但是在oracle数据库, 很少听说需要用到"分表", 因为分区就是最好的"分表". 之前遇到某移动客户的账务系统做了分表, 那SQL写起来是相对的尬,如果架构师能多了解一些分区就好了.

同样, 加索引和调整SQL写法也是必不可少的, 这是每个数据库优化都躲不过的, 有时候即使做了分区, SQL写法配合不上也是白扯.

客户3:

这是一个ETL加报表输出库, 很多SQL执行时间在1~2小时以上,还有一些执行7~8个小时以上最后报ora-01555错误,相当于消耗了大量的系统资源, 最后得到了一个寂寞.

这个数据库最大的问题是修改了一个重要的优化器参数optimizer_mode, 将这个参数恢复到默认值后, 再加上其他的一些优化手段, 原来执行几个小时的SQL, 执行时间都降到了1分钟以下. 有的数据库参数可以根据实际情况做一些调整, 但是像optimizer_mode这种参数, 千万不要动, 这是在做"劣化", 而不是做优化.

介绍完3个优化案例, 再谈谈优化相关的一些理论, 索引是SQL优化最基本的技术, 也是OLTP系统最主要的优化手段, 很多人都觉得简单, 但就是这项技术, 我花了整整两天的时间给学员做培训.

下面是我看到的几个关于索引的优化案例, 看完之后感觉优化人员对索引的理解可能存在一些偏差, 举两个例子:

1. 下面3个sql, 创建索引应该能够带来很大的性能提升, 但是把常量1加到索引做联合索引, 是完全没有必要的, 这个做法暴露了对索引理解的不足:

SELECT ... FROM xxx WHERE col1 = :B1 OR col2 = :B1 ;

create index .. on xxx(col1,1);

create index .. on xxx(col2,1);

select ... from xxx WHERE col1 || col2= :B1;

create index .. on xxx(col1||col2,1);

SELECT ... FROM xxx WHERE col1= TRIM(:B1 );

create index .. on xxx(col1,1);

把常量加到联合索引, 某些特殊情况确实需要, 但都不是上面这些情况.

2. 下面这个SQL, 给出的优化建议存在多个问题:

select ... from xxx

where c1=:b1 and c2=:b2 and c3=:b3 and c4=:b4 and c5=:b5;

当前已经存在(c1,c2,c3,c4,c5) 5 字段联合索引 , 5个字段的NDV(number of distinct value) 分别是 97, 1, 1, 264, 572519 (表上记录数 650万)

优化人员给出的建议是新建(c5,c4,c1,c2,c3) 5字段联合索引.

这个新建索引对当前SQL起到的优化作用可以说是微乎其微.因为都是等值条件, 联合索引字段先后顺序基本上没有影响. 并不是说NDV大的字段就一定要放到联合索引的最前面, 没有这样的理论.

上面的建议涉及到几个索引的基本理论:

不需要把where 后面所有的条件都加到联合索引(肥大的索引有很多弊端, 这里不一一列举), 这个索引只用c4,c5 两个字段联合基本上就足够了.

如果是等值条件, 联合索引字段先后顺序差别很小,基本可以忽略不计(c5,c4也是一样的)

把NDV=1的c2和c3加到联合索引, 意义不大; ndv=1 字段加入到索引,只在某些特殊情况才有意义, 比如大部分是null值/查找不存在的值/加了rownum<=xx等.

结语:

很多人认为数据库优化很简单, 几乎每个DBA的简历上都写着精通数据库优化. 而实际情况却是大部分DBA遇到数据库性能问题时, 还是希望能通过修改数据库的初始化参数得到解决, 最多也只是加几个简单索引, 固定一些SQL的执行计划而已. 很少从业务和开发的角度提出解决性能问题的根本原因.

而开发人员对越来越慢的系统, 有的会抱怨DBA维护水平差, 有的会认为硬件资源不足, 较少从架构设计/SQL写法等自身原因分析问题, 而这部分恰恰是导致性能恶化问题的主要根源.

当DBA和开发把知道的优化方法都使出来之后, 数据库性能还是不能得到明显的改善, 就只能寄希望于高级硬件上了, 高级硬件能解决一大部分性能问题, 但是无法解决诸如SQL写法低效/少索引/统计信息过旧/参数设置不当/优化器缺陷等其他诸多问题.

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-11-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老虎刘谈oracle性能优化 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档