一次数据库性能问题处理引发的JDBC参数设置思考

近期某环境下系统,出现大面积页面访问缓慢情况,每个页面交易响应时间2-5秒,严重超过平日访问阈值。

经排查分析,问题主要出现在数据库,生成AWR得到32C的数据库DBtime每小时采样达到4800。进一步分析发现主要等待事件library cache lock,library cache:mutex X。

进一步分析发现DB主要耗时在SQL解析及解析失败上。

生成10035事件,发现数据库日志中有大量解析失败错误,且解析失败的SQL全部带有ROWID列。

将该类SQL反馈研发部门,反馈未在SQL中添加ROWID。那么ROWID是从何而来的呢,查询相关资料最后定位到JDBC连接参数设置不合理。

那么JDBC连接有哪些参数,各个参数作用是什么,参数设置会对SQL解析产生什么样的影响呢?带着这些问题,笔者对JDBC参数设置对SQL解析影响做了针对性实验,大家跟着我来一探究竟吧。

JDBC连接参数说明

JDBC连接数据库主要有两个类分别是PreparedStatement和Statement,两个类可以带三个参数分别是:ResultSetType、ResultSetConcurrency、ResultSetHoldability。由于参数ResultSetConcurrency和ResultSetHoldability对数据库连接影响小,且使用限制较多,因此这里重点介绍参数:ResultSetType。

ResultSetType

ResultSetType的可选值有三个,每个值及对应的作用如下:

ResultSet.TYPE_FORWARD_ONLY:为空时默认值,该值支持结果集前滚遍历操作。

ResultSet.TYPE_SCROLL_INSENSITIVE:该值支持结果集后滚,随机,取后,取前等操作,当其它会话对数据库中数据做出更改时,结果集不随之刷新。

ResultSet.TYPE_SCROLL_SENSITIVE:该值支持结果集后滚,随机,取后,取前等操作,当其它会话对数据库中数据做出更改时,改更会刷新到本结果集中,使结果集中数据与数据库数据实时一致。

连接参数测试

测试环境情况如下表:

在测试数据库中建表psname,psdept,psobj并插入数据,表结构如下:

在Oracle中每次程序调用前清空数据库缓存(alter system flush shared_pool清空缓存便于观察SQL执行情况),程序调用结束后查询V$SQL视图,查看解析执行的SQL。

参数设置对解析影响

ROWID是Oracle用于查询表中一行记录的地址,一旦查询中出现了SUM,DISTINCT等聚合或去重函数,获取的数据与单行记录地址不再一一对应,因此多表连接、单表查询带聚合函数、数据去重等SQL解析过程不会出现ROWID,如果出现ROWID则会报解析错误。

测试方法:

设置JDBC参数ResultSetType=ResultSet.TYPE_FORWARD_ONLY。

在数据库服务端执行:alter system set events '10035 trace name context forever,level 1',跟踪解析SQL。

执行程序查看Oracle内部视图V$SQL执行解析结果并截图。

调整ResultSetType值为TYPE_SCROLL_SENSITIVE和TYPE_SCROLL_INSENSITIVE重复1、2步骤执行测试。

比对不同参数设置下Oracle中V$SQL显示结果,参数设置对数据库解析影响。

1)测试一,单表简单SQL1:select ID,NAME from psname。

测试结果如下表,执行过程后台未见解析报错(如图3-0),在测试过程中当ResultSetType为TYPE_SCROLL_SENSITIVE时数据库执行会自动加入rowid列。其中12C给rowid自动增加一个别名(如图4-1),11G则不会(如图4-2)。

图3-0 10035事件记录的日志,无错误输出

图3-1 V$SQL查询的最终执行结果

图4-1 V$SQL查询的最终执行结果

图4-2 V$SQL查询的最终执行结果

2)测试二,单表带聚合函数或去重SQL语句:

① select  count(ID) as SUM,dept_id from psname group by dept_id。

② select DISTINCT(OWNER) as OWNER, OBJECT_TYPE FROM TEST001.PSOBJ。

经测试ResultSetType设置为TYPE_FORWARD_ONLY,TYPE_SCROLL_INSENSITIVE编译不报错,解析执行正常。连接参数ResultSetType设置为TYPE_SCROLL_SENSITIVE时,解析会报错,由于数据库自身编译纠错机制,最终数据库执行结果正常,该情况测试结果如下表:

图5-1 10035事件记录的报错日志

图5-2 V$SQL查询的最终执行结果

图6-1 10035事件记录的报错日志

图6-2 V$SQL查询的最终执行结果

3)测试三,表关联查询SQL3:select

n.id,n.name,d.dept_name from TEST001.PSNAME n ,TEST001.psdept d where n.dept_id=d.dept_id and d.dept_name='Sales'。

经测试ResultSetType设置为TYPE_FORWARD_ONLY,TYPE_SCROLL_INSENSITIVE编译不报错,解析执行正常。连接参数ResultSetType设置为TYPE_SCROLL_SENSITIVE时,解析会报错,由于数据库自身编译纠错机制,最终数据库执行结果正常,该情况测试结果如下表:

图7-1 10035事件记录的报错日志

图7-2 V$SQL查询的最终执行结果

4)测试四,带条件全列查询SQL4:select * from psname where dept_id=2。

经测试ResultSetType设置为TYPE_FORWARD_ONLY,TYPE_SCROLL_INSENSITIVE编译不报错,解析执行正常。连接参数ResultSetType设置为TYPE_SCROLL_SENSITIVE时,解析会报错,由于数据库自身编译纠错机制,最终数据库执行结果正常,该情况测试结果如下表:

图8-1 10035事件记录的报错日志

图8-2 V$SQL查询的最终执行结果

5)结论:从以上测试情况看出,当ResultSetType等于TYPE_SCROLL_SENSITIVE时,所有SQL编译过程均会在查询结果集前增加ROWID列。当增加ROWID产生语法解析错误时(通过10035事件生产的日志可知),数据库通过内部纠错算法得到正确SQL再执行,于是在V$SQL表中看到不带ROWID的正确已执行的SQL。当JDBC参数ResultSetType等于TYPE_FORWARD_ONLY,TYPE_SCROLL_INSENSITIVE时SQL解析都不会增加ROWID,此两种情况下SQL执行前后完全一致,数据库日志无解析报错输出。

在测试过程中还通过调整不同的环境因素进行测试,发现数据库版本、驱动版本、JDK版本对数据库解析后ROWID产生无影响,对比分析如下表:

参数设置对查询更新数据影响

测试说明:根据参数解释当resultSetType为TYPE_SCROLL_SENSITIVE时,查询结果集会随着数据修改动态更新,其他值无此类特性因此此处测试只测该情况即可。

测试过程:

① 设置JDBC连接参数ResultSetType=ResultSet.TYPE_SCROLL_SENSITIVE。

② 调用程序执行查询。

③ 进入断点,更新psname表中dept_id字段值。

④ 查看JAVA程序输出图,查看数据库表中结果值图,断点循环取值时查看resultset对应ID值。若JAVA输出结果集与数据库查询一致表明,数据动态更新。

测试结果如下表:

图9:JAVA程序输出结果

图10:数据库查询结果

结论:JDBC连接参数ResultSetType设置为TYPE_SCROLL_SENSITIVE均不会动态更新结果集。

参数设置对JVM影响

测试方法:调整JVM堆大小,查询数据库大表结果集来测试不同参数对查询结果集影响。

测试过程:

① 将JVM大小设置成-Xmx128m -Xms64m -Xmn32m -Xss16m。

② 执行SQL向表PSOBJ插入150万条数据,使表数据大于128M。

③ 设置参数ResultSetType=ResultSet.TYPE_FORWARD_ONLY,程序中执行如下查询:

④ 执行程序查看控制台输出结果并截图。

⑤ 调整ResultSetType值为TYPE_SCROLL_SENSITIVE和TYPE_SCROLL_INSENSITIVE重复1、2步骤执行测试。

测试结果如下表:

图13

图14

结论:当查询结果集大于JVM时,Oracle在ResultSetType为TYPE_FORWARD_ONLY时正常查询,其他值时内存异常;MySQL在所有情况下都会出现内存溢出的情况。

JDBC参数设置建议

从以上测试中我们不难发现,由于开发人员对JDBC连接参数设置不合理,导致了数据库解析SQL产生大量报错,引起了library cache lock,library cache:mutex X等待事件,造成数据库性能急剧下降,最终造成业务系统响应严重超时。

由此建议JDBC中ResultSetType参数设置:若只做一般查询默认值即可;

若需要对结果集进行遍历、比较等相关操作可设置为TYPE_SCROLL_INSENSITIVE;

不推荐使用TYPE_SCROLL_SENSITIVE,因为该参数不会动态更新结果集,且该参数可能导致数据库SQL解析错误而执行二次解析消耗数据库资源;

若查询结果集过大,建议使用默认,避免结果集过大造成JVM内存溢出。

Jdbc访问mysql查询聚合函数_JDBC连接参数设置对Oracle数据库的影响分析相关推荐

  1. mysql的聚合函数文档_MySQL聚合函数

    MySQL聚合函数 MySQL的聚合函数用于对多个值执行计算,并将结果返回为单个值,如所有值的平均值,所有值的总和以及某些值组中的最大值和最小值.我们通常将聚合函数与数据查询语言中的SELECT语句一 ...

  2. Spring使用JDBC访问MySQL数据库

    在Java应用程序开发中,使用JDBC访问MySQL数据库是Java开发者常用的技术.在Spring框架中,Spring对JDBC又进行了封装,简化了程序访问数据库的复杂度.本课主要讨论在Spring ...

  3. 【MySQL】聚合函数

    一.五大常用聚合函数 SUM():求总和,只适用于数值类型字段,如果是字符串类型不会报错会返回0,会自动过滤空值 AVG():求平均值,只适用于数值类型字段,字符串类型不会报错会返回0,会自动过滤空值 ...

  4. mysql 聚合函数求乘积_手把手教你mysql(五)聚合函数

    手把手教你mysql(五)聚合函数 一: 聚合函数 1.1.COUNT()函数 1. COUNT()函数用来统计记录的条数: 2. 与GOUPE BY 关键字一起使用: 我这边仍然使用的是t_stud ...

  5. mysql的聚合函数综合案例_MySQL常用聚合函数详解

    一.AVG AVG(col) 返回指定列的平均值 二.COUNT COUNT(col) 返回指定列中非NULL值的个数 三.MIN/MAX MIN(col):返回指定列的最小值 MAX(col):返回 ...

  6. MySQL中concat函数(连接字符串)

    MySQL中concat函数(连接字符串) MySQL中concat函数 使用方法: concat(str1,str2,-) 返回结果为连接参数产生的字符串.如有任何一个参数为NULL ,则返回值为 ...

  7. java通过jdbc访问mysql,update数据返回值的思考

    java通过jdbc访问mysql,update数据返回值的思考 先不说那么多,把Java代码贴出来吧. public static void main(String[] args) throws I ...

  8. MYSQL字符串聚合函数

    MYSQL字符串聚合函数学习笔记 mysql中可存储多种数据类型,varchar(字符串)则是其中一种最常见的类型.在对字符串类型进行读取时,我们有时候需要对取出的原始数据进行操作,这个操作在程序里很 ...

  9. mysql相关聚合函数应用商品分类表

    多表查询 一.多表之间建表关系分析 ​ 一对多:商品和分类 ​ 一对一:人和身份证(比较少) ​ 多对多:课程和学生 ​ 拆分成2个1对多的关系,建立一个中间表,让中间表的两个外键分别去指向两张表的主 ...

最新文章

  1. oracle cache keep pool,请问:alter table ……storage(buffer_pool keep) 与cache的区别
  2. shell实例第22讲:shell中分隔符IFS用法
  3. 怎么将数据进行正太转化_想要将电脑音频进行录制怎么操作
  4. linux 应用层时间和随机数,zigbee cc2530时间
  5. 求 LCA 的三种方法
  6. mysql表空间_浅谈mysql中各种表空间(tablespaces)的概念
  7. 性能测试利器工具来了,生产环境全链路压测工具
  8. 未找到依赖项 ‘org.apache.spark:spark-hive_2.11:2.4.5‘
  9. 网络设备中的路由器的作用,如何设置路由器,上网、IP分配、黑白名单、访问量...
  10. Linux - Ubuntu中使用7zip和zip命令
  11. [Python程序设计] 用Scrapy爬取学堂在线计算机类课程页面的信息
  12. 【ZZULIOJ】1092: 素数表(函数专题)
  13. SNAKER 工作流
  14. 每周一喂丨网络黑灰产工具“八大样儿”
  15. Android 9.0 SystemUI 下拉状态栏快捷开关
  16. 第二届SLAM暑期学校和全国技术论坛有感
  17. MATLAB仿真节点个数和节点通信半径与网络连通率的关系,WSN实验
  18. Groovy Script 获取当前时间函数
  19. OpenGL-立方体贴图之天空盒
  20. HQChart使用教程30-K线图如何对接第3方数据20-信息地雷公告数据

热门文章

  1. 张国栋 linux进程,张国栋(栋梁)造价定额设计:BIM技术应用于装配式建筑的优势...
  2. dateformat java 格式_java Date日期类和SimpleDateFormat日期类格式
  3. delphi socket 怎样把接收到的二进制数据转换成字符串显示_广东qp用户数据免费咨询...
  4. 牛逼!Python的类和对象(长文系列第⑤篇)
  5. 年轻人不讲武德,居然在简历中藏木马!
  6. 爬一爬那些年你硬盘存过的老师
  7. 分页池内存持续增长_Java技术学习之对虚拟机(JVM)内存模型的分析
  8. gre biochemistry_【备考精选】2020年11月6日GRE写作Issue预测分享
  9. 黑苹果关机重启后蓝牙连接不上_手机要关机吗,要贴膜吗,要套壳吗?看完这条,都有答案了_政务_澎湃新闻...
  10. 从零开始数据科学与机器学习算法-数据预处理与基准模型-01