PreparedStatementCache的意义
Oracle支持游标,一个PreparedStatement对应服务器一个游标,如果PreparedStatement被缓存起来重复执
行,PreparedStatement没有被关闭,服务器端的游标就不会被关闭,性能提高非常显著。在类似SELECT * FROM T WHERE
ID = ?这样的场景,性能可能是一个数量级的提升。
由于PreparedStatementCache性能提升明显,DruidDataSource、DBCP、JBossDataSource、WeblogicDataSource都实现了PreparedStatementCache。
PreparedStatementCache带来的问题
阿里巴巴在使用jboss连接池做PreparedStatementCache时,遇到了full gc频繁的问题。通过mat来分析jmap
dump的结果,发现T4CPreparedStatement占内存很多,出问题的几个项目,有的300M,有的500M,最夸张的900M。这些应用
都是用jboss连接池访问Oracle数据库,T4CPreparedStatement是Oracle JDBC
Driver的PreparedStatement一种实现。
oracle driver不是开源,通过逆向工程以及mat分析,发现其中占内存的是字段char[] defineChars,defineChars大小的计算公式是这样的:
defineChars大小 = rowSize * rowPrefetchCount
|
rowPrefetchCount在Oracle中,缺省值为10。
其中rowSize是执行查询设计的每一列的大小的和。计算公式是:
rowSize = col_1_size + col_2_size + ... + col_n_size
|
很悲剧,有些列数据类型是varchar2(4000),于是rowSize巨大,很多个表关联的SQL,rowSize可能高达数十K,再乘以
rowPrefetchCount,defineChars大小接近1M。可以想想,maxPoolSize设置为
30,PreparedStatementCacheSize设置为50的场景下,是可能导致PreparedStatementCache占据上G的内
存。
实际测试得到的结果如下:
varchar2(4000) |
col_size 4000 chars |
clob -> col_size |
col_size 4000 bytes |
实际占据内存的公式:
占据内存大小峰值 = defineChars大小 * PreparedStatementCacheSize * MaxPoolSize
|
我们实际分析,一个应用运行的SQL大约数百条,PreparedStatementCacheSize为
50,PreparedStatementCache的算法为LRU,很多的SQL执行之后,在Cache中HitCount为0就被淘汰了,淘汰的过
程,其位置从第1移到第50,这个漫长的过程导致了defineChars不能够被young gc回收。
Druid的解决方案
命中率低的SQL,不持有defineChars缓存。
OracleStatement提供了clearDefines方法,用于清理defineChars。DruidDataSource在
PreparedStatement加入Cache时,如果发现hitCount <
1,就调用clearDefines方法。通过这种方式,避免了命中率为0的PreparedStatement占用内存。测试表明,200个
SQL,PreparedStatementCacheSize为50的场景,能够减少一半的young gc。(生产环境还没做测试)
根据PreparedStatement执行的结果,计算RowPrefetch大小
添加PreparedStatementCache计数器
包括:
- PreparedStatementCacheCurrentSize
- PreparedStatementCacheDeleteCount 缓存删除次数
- PreparedStatementCacheHitCount 缓存命中次数
- PreparedStatementCacheMissCount 缓存不命中次数
- PreparedStatementCacheAccessCount 缓存访问次数
通过这五个计数器,我们清晰了解PreparedStatementCache的工作情况,然后根据实际情况调整。
分享到:
相关推荐
Oracle 数据库多语言入库问题的解决方案是针对企业在国际化进程中遇到的多国语言信息存储难题,尤其是在使用Oracle数据库时,由于字符集的不兼容性导致非中文语言数据入库时出现乱码。Oracle数据库作为全球广泛使用...
Oracle数据库中文乱码问题解决方案 Oracle数据库中文乱码问题是指在Oracle数据库中,中文字符无法正确显示或出现乱码的问题。这种问题通常是由于数据库服务器端和客户端字符编码设置不正确引起的。本文将提供一个...
本文将详细讨论三个常见的Oracle数据库操作错误及其解决方案。 首先,错误`ORA-01650: unable to extend rollback segment NAME by NUM intablespace NAME`是由于回滚段表空间不足导致的。回滚段用于保存事务的回滚...
Oracle数据库归档日志满问题解决方案 Oracle数据库中的归档日志是指...通过查看归档日志的状态、位置和大小,检查flash recovery area的使用情况,我们可以了解归档日志的使用情况,并采取相应的解决方案来解决问题。
ORACLE数据库中文显示乱码问题的解决,系统中ORACLE数据库在安装后不能正确显示中文,而是显示为'???'等此类乱码。他人总结分析的内容,可以参考下。
Oracle数据库操作常见错误及解决方案[借鉴].pdf
Oracle 数据库字符集问题解决方案大全 Oracle 数据库字符集问题解决方案大全中,提出了 Oracle 数据库汉字显示异常的解决方案。该文档涵盖了字符集的概念、字符集的设置、字符集的影响因素、解决汉字显示异常的...
此外,监控数据库性能,例如通过DBA_HIST views或ADDM(Automatic Database Diagnostic Monitor)报告,可以发现并解决问题。 数据安全是Oracle数据库管理的重点。应实施严格的权限管理,遵循最小权限原则,避免...
Oracle数据库作为一款高性能的大型关系数据库管理系统,广泛应用于各行业的关键业务中。随着业务规模的扩大和数据量的增长,数据库运维和故障应急处理变得尤为重要。本文档即为Oracle数据库的日常运维及应急故障处理...
"医院信息系统ORACLE数据库升级解决方案" 在医院信息系统中,ORACLE数据库升级是一个非常重要的任务。由于ORACLE公司已经不再对一些较老版本的数据库系统提供技术支持,这使得许多医院面临数据库升级的问题。本文将...
Oracle 数据库服务器 IO 高的问题需要深入理解和分析,以便更好地解决问题。本文旨在提供一些实用的解决方案和方法,帮助系统管理员和存储管理员更好地理解 Oracle 数据库服务器 IO 高的问题,并提高 Oracle 数据库...
连接 Oracle 数据库是每个开发者和数据库管理员都需要掌握的基本技能,但是很多人在连接 Oracle 数据库时都会遇到各种问题,本文将详细介绍如何连接 Oracle 数据库及故障解决办法。 首先,在连接 Oracle 数据库之前...
Oracle 数据库安装问题及其解决方法 Oracle 数据库是一种关系型数据库管理系统,广泛应用于金融、电信等行业。然而,在安装 Oracle 数据库时,会出现各种问题,影响数据库的正常使用。以下是Oracle 数据库安装问题...
Oracle数据库规划设计和运行维护方案是确保数据库系统能够高效、稳定运行的关键。在这一方案中,会涉及多种技术和组件,包括但不限于高可用性(HA)、真正应用集群(RAC)、数据保护(DataGuard)、备份与恢复(RMAN...
Oracle 数据库升迁时字符集问题的解决 Oracle 数据库升迁时字符集问题是许多开发者和数据库管理员头痛的问题。这个问题的解决需要了解 Oracle 数据库升迁过程中的字符集问题,并掌握 Export 和 Import 命令的使用...
第二讲:Oracle实例中内存结构 第三讲:Oracle实例中后台进程管理 第四讲:Oracle数据数据文件管理 第五讲:Oracle数据库在线日志文件管理 第六讲:Oracle数据库归档日志文件管理 第七讲:Oracle数据库控制文件管理...
在PPT中,可能详细阐述了需求分析、系统架构设计、数据库表结构设计等步骤,以及可能遇到的问题和解决方案。这通常会涉及数据库的概念模型和逻辑模型的转换,以及如何使用SQL语句创建表、视图和存储过程等。同时,...
本文档主要是解决Oracle数据库使用过程中,经常出现的SID无法识别问题的一个解决方案。