问题现象
同一个sql有两个执行计划,是否合理?
它的EXECUTIONS,ELAPSED_TIME等统计信息怎么看,是独立分开的还是统一计算的?
如下图:
问题影响版本
tpcc测试:23.2.1.100
问题的风险及影响
影响EXECUTIONS等sql统计信息的计算
问题发生原因
同一条sql,特别是绑定参数的sql,参数类型不同,会导致生成不同的执行计划。
分析及处理过程
例子测试分析
复现例子:
如上,第二个参数是int和double时,生成了两个执行计划,有两个plan_hash_value,如下图:
后跑几次,发现其中executions、cpu_time这些值共享,统计到一起,所以两条结果的这些字段值一样。
代码分析
select * from v$sql; 调用过程
v$sql是动态表,数据都存放在内存中。
ftsqlFetch 数据:
- 每一条sql都是一个anlcontext对象,存放在sqlpool中。
- anlGetNextNewPlan(stmt, ctxCursor),通过这个接口从sqlpool中,根据poolid和bucketid从sqlpool中取的anlcontext,根据anlcontext的plan取数据。
- 一个plan一条数据,每条数据的plan_hash_value都不一样。
- 统计数据存放在anlcontext中的stats:iostat、timestat、runstat、gcstat
所以同一条sql不同的plan,stats数据其实相同。
anlcontext管理
pool内存池分配方式
SGA总内存分配接口:anrCreateGlobalArea
SGA总内存组成方式:data buff + vm buff + large pool + redo buff + shared pool + dbwr buff + audit buff + app pool + hot cache + pq pool +job pool
globalArea:anrStartInstance时一次性申请如下表空间数据,
shared pool 分配
分配接口:setShareBuffers
shared pool内存拆分:sql pool + dc pool + lock pool + cursor pool等
sql pool buf分配:
调用接口:anlCreateSQLPool
sql pool组成:main pool buff + pl pool buff
sql buff分配
kernel buff分配
缓存相关视图
经验分享
1、同一个sql,有多个执行计划,是正常现象
2、v$sql中的executions、cpu_times等一些统计字段,同一个sql都是同样的值,不能做加减等操作。