问题现象

同一个sql有两个执行计划,是否合理?

它的EXECUTIONS,ELAPSED_TIME等统计信息怎么看,是独立分开的还是统一计算的?

如下图:

问题影响版本

tpcc测试:23.2.1.100

问题的风险及影响

影响EXECUTIONS等sql统计信息的计算

问题发生原因

同一条sql,特别是绑定参数的sql,参数类型不同,会导致生成不同的执行计划。

分析及处理过程

例子测试分析

复现例子:

drop table if exists tmp2;
create table tmp2(c1 int,c2 double,c3 int,c4 int,c5 int,c6 int,c7 int,c8 timestamp,c9 varchar(500),c10 int) ;

如上,第二个参数是int和double时,生成了两个执行计划,有两个plan_hash_value,如下图:

后跑几次,发现其中executions、cpu_time这些值共享,统计到一起,所以两条结果的这些字段值一样。

代码分析

select * from v$sql; 调用过程

v$sql是动态表,数据都存放在内存中。

anrDedicatedServiceNoLogin
anrResponse
anrDirectExecute
anlExecute
doAnlExecute
doExecute
fetchQuery
fetchPlanWithPreProj
anlFetchPlan
doAnlFetchPlan
fetchSelectPlan
anlFetchPlan
doAnlFetchPlan
fetchTableFullScan
ankFetch
ankFtFetch
{
ftSqlFetch //获取一条v$sql数据
ankExecFilter //filter筛选
}

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管理

sqlpool有两个:
typedef enum EnAnlPoolType {
ANL_MAIN_POOL = 0, -- 普通sql pool
ANL_PL_POOL, -- pl sql pool
__ANL_POOL_TYPE_COUNT__
} AnlPoolType; //生成一个新sql的anlcontext,调用流程
doParseDML
anlHashSQL // 生成sql hash
anlTryReuseContext // 从 inst->sqlpool,buckets中比较已有的anlcontext,是否有同一个sql
anlCreateContext // 没有从sqlpool中找到,从ANL_MAIN_POOL中申请新的anlcontext
anlPoolInsert // anlcontext插入pool中,anlLruInsert lru插入 //第二条执行计划,调用流程
//sql的第二个plan,在anlexecute中生成。放在anlcontext的planContexts中
execExplain
replaceNewPlan
doReplaceNewPlan
anlCreateAndUseNewPlan
anlInsertPlan

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时一次性申请如下表空间数据,

typedef enum EnMzoneId {
MZONE_DATA_BUFFER = 0, // 配置参数:DATA_BUFFER_SIZE attr->dataBufSize(64M)
MZONE_TEMP_BUFFER, // 配置参数:VM_BUFFER_SIZE attr->tempBufSize (32M)
MZONE_LARGE_POOL, // 配置参数:LARGE_POOL_SIZE attr->largePoolSize(16M)
MZONE_LOG_BUFFER, // 配置参数:REDO_BUFFER_SIZE attr->logBufSize(8M)
MZONE_HOT_CACHE, // 配置(隐藏)参数:_HOT_CACHE_SIZE attr->hotCacheSize(16M)
MZONE_SHARE_POOL, // 配置参数:SHARE_POOL_SIZE attr->sharePoolSize(256M)
MZONE_APP_POOL, // 配置参数:WORK_AREA_POOL_SIZE attr->appPoolSize(16M)
MZONE_DBWR_BUFFER, // 配置参数:DBWR_BUFFER_SIZE attr->dbwrBufSize(4M)
MZONE_JOB_POOL, // 默认4M
MZONE_PQ_POOL, // 配置(隐藏)参数:PQ_POOL_SIZE attr->pqPoolSize(parallel execute buff 默认:16M)
MZONE_AUDIT_BUFFER, // 配置参数:AUDIT_QUEUE_SIZE attr->auditQueueSize(16M)
MZONE_COUNT,
} MzoneId;

shared pool 分配

分配接口:setShareBuffers

shared pool内存拆分:sql pool + dc pool + lock pool + cursor pool等

typedef enum EnSharePoolItemId {
SHARE_SQL_POOL = 0, // 配置(隐藏)参数:SQL_POOL_SIZE attr->sqlPoolBuf (sqlPoolSize:百分比默认50)
SHARE_DC_POOL, // 配置(隐藏)参数:DICTIONARY_CACHE_SIZE profile->dictCache (dictCacheSize:百分比默认25)
SHARE_LOCK_POOL, // 配置(隐藏)参数:LOCK_POOL_SIZE profile->lockPool(lockPoolSize:16M)
SHARE_CURSOR_POOL, // 配置(隐藏)参数:CURSOR_POOL_SIZE profile->cursorPool(cursorPoolSize:32M)
SHARE_DSTB_POOL, // 配置(隐藏)参数:DSTB_POOL_SIZE (分布式,dstbPoolSize:默认百分比0 )
SHARE_GCS_RESOURCE, // 集群(主备)才有 根据dataBufSize的block数计算出来
SHARE_GLS_RESOURCE, // 集群才有 根据dataBufSize的block数计算出来
SHARE_GRC_REQUEST, // 集群才有 根据lockPoolSize计算
SHARE_GCS_PASTCOPY, // 集群才有 根据 maxHandlers计算
SHARE_COUNT, // 剩余 profile->sharePool中
} SharePoolItemId;

sql pool buf分配:

调用接口:anlCreateSQLPool

sql pool组成:main pool buff + pl pool buff

ANL_MAIN_POOL: (9/10) * sqlpoolsize
mainPoolSize = attr->sqlPoolSize - plPoolSize;
AnlPool* mainPool = &inst->sqlPool[ANL_MAIN_POOL]; ANL_PL_POOL:(1/10) * sqlpoolsize
#define ANL_PL_POOL_MEMORY_PCT (CodUint64)10
#define ANL_PL_POOL_SIZE(totalSize) ((totalSize) * ANL_PL_POOL_MEMORY_PCT / 100)
plPoolSize = ANL_PL_POOL_SIZE(attr->sqlPoolSize)

sql buff分配

static void setSQLBuffers()
{
AnlAttr* attr = anlGetAttr(gInstance->sql);
attr->appPoolBuf = g_MemoryZones[MZONE_APP_POOL].buffer;
attr->jobPoolBuf = g_MemoryZones[MZONE_JOB_POOL].buffer;
attr->jobPoolSize = g_MemoryZones[MZONE_JOB_POOL].size;
attr->pqPoolBuf = g_MemoryZones[MZONE_PQ_POOL].buffer;
attr->auditQueueBuf = g_MemoryZones[MZONE_AUDIT_BUFFER].buffer;
}

kernel buff分配

static void setKernelBuffers()
{
KernelAttr* profile = ankGetKernelAttr(gInstance->kernel);
profile->dataBuf = g_MemoryZones[MZONE_DATA_BUFFER].buffer;
profile->logBuf = g_MemoryZones[MZONE_LOG_BUFFER].buffer;
profile->tempBuf = g_MemoryZones[MZONE_TEMP_BUFFER].buffer;
profile->hotCache = g_MemoryZones[MZONE_HOT_CACHE].buffer;
profile->largePool = g_MemoryZones[MZONE_LARGE_POOL].buffer;
profile->dbwrBuf = g_MemoryZones[MZONE_DBWR_BUFFER].buffer;
}

缓存相关视图

经验分享

1、同一个sql,有多个执行计划,是正常现象

2、v$sql中的executions、cpu_times等一些统计字段,同一个sql都是同样的值,不能做加减等操作。

【YashanDB知识库】绑定参数,同一个sql多个执行计划的问题的更多相关文章

  1. SQL Server 优化-执行计划

    对于SQL Server的优化来说,优化查询可能是很常见的事情.由于数据库的优化,本身也是一个涉及面比较的广的话题, 因此本文只谈优化查询时如何看懂SQL Server查询计划.毕竟我对SQL Ser ...

  2. 了解Sql Server的执行计划

    前一篇总结了Sql Server Profiler,它主要用来监控数据库,并跟踪生成的sql语句.但是只拿到生成的sql语句没有什么用,我们可以利用这些sql语句,然后结合执行计划来分析sql语句的性 ...

  3. 【MS SQL】通过执行计划来分析SQL性能

    原文:[MS SQL]通过执行计划来分析SQL性能 如何知道一句SQL语句的执行效率呢,只知道下面3种: 1.通过SQL语句执行时磁盘的活动量(IO)信息来分析:SET STATISTICS IO O ...

  4. 官方文档:11G新特性SQL PLAN BASLINE 执行计划基线

    什么是SQL执行计划管理? SQL计划管理(SQL plan management)是一咱预防机制,记录和评估SQL语句的执行计划.SQL plan management的主要功能是sql plan ...

  5. oracle中查看sql语句的执行计划

    1.在pl/sql中打开cmd命令容器 2.在cmd命令窗口中输入:explain plan for select * from t; 3.查看sql语句的执行计划:select * from tab ...

  6. SQL Server实际执行计划COST"欺骗"案例

    有个系统,昨天Support人员发布了相关升级脚本后,今天发现系统中有个功能不能正常使用了,直接报超时了(Timeout expired)的错误.定位到相关相关存储过程后,然后在优化分析的过程中,又遇 ...

  7. SQL Server控制执行计划

    为了提高性能,可以使用提示(hints)特性,包含以下三类: 查询提示:(query hints)告知优化器在整个查询过程中都应用某个提示 关联提示:(join hints)告知优化器在查询的特定部分 ...

  8. 【Oracle】三种方式查看SQL语句的执行计划

    查看执行计划的方式有三种: EXPLAIN PLAN .V$SQL_PLAN .SQL*PLUS AUTOTRACE 1.EXPLAIN PLAN: 显示执行相应语句时可以使用的理论计划 读取执行计划 ...

  9. 性能测试四十一:sql案例之慢sql配置、执行计划和索引

    MYSQL 慢查询使用方法MYSQL慢查询介绍分析MySQL语句查询性能的问题时候,可以在MySQL记录中查询超过指定时间的语句,我们将超过指定时间的SQL语句查询称为“慢查询”.MYSQL自带的慢查 ...

  10. 程序员眼中的 SQL Server-执行计划教会我如何创建索引?

    先说点废话 以前有 DBA 在身边的时候,从来不曾考虑过数据库性能的问题,但是,当一个应用程序从头到脚都由自己完成,而且数据库面对的是接近百万的数据,看着一个页面加载速度像乌龟一样,自己心里真是有种挫 ...

随机推荐

  1. VS2015 、VS2017 MFC输出日志到控制台窗口

    原来使用VS2010建立的项目,安装VS2017后,发现MFC无法通过调试窗口输出printf打印的内容,在CSDN上找到了一个解决方案,使用后恢复打印调试信息功能,推荐如下: https://blo ...

  2. 操作系统|SPOOLing(假脱机)技术

    什么是假脱机技术,它可以解决什么问题? 什么是脱机技术 要回答什么是假脱机技术,首先我们需要知道什么是脱机技术.<计算机操作系统(第四版)>写道: 为了解决人机矛盾及CPU和I/O设备之间 ...

  3. Doris failed to initialize storage reader. tablet=106408, res=[NOT_IMPLEMENTED_ERROR]to be implemented

    Apache Doris 2.3 以下的版本会存在一个 bug,导致数据在合并时存在异常,在后续查询该字段数据时会提示 [1105] [HY000]: errCode = 2, detailMessa ...

  4. 我从 Python 潮流周刊提取了 800 个链接,精选文章、开源项目、播客视频集锦

    你好,我是豌豆花下猫.前几天,我重新整理了 Python 潮流周刊的往期分享,推出了第 1 季的图文版电子书,受到了很多读者的一致好评. 但是,合集和电子书的篇幅很长,阅读起来要花不少时间.所以,为了 ...

  5. 手写数字识别-使用TensorFlow构建和训练一个简单的神经网络

    下面是一个具体的Python代码示例,展示如何使用TensorFlow实现一个简单的神经网络来解决手写数字识别问题(使用MNIST数据集).以下是一个完整的Python代码示例,展示如何使用Tenso ...

  6. 【工具】SpringBoot项目如何查看某个maven依赖是否存在以及依赖链路

    当我在SpringBoot项目中想加个依赖,但是不确定现有依赖的依赖的依赖.....有没有添加过这个依赖,怎么办呢?如果添加过了但是不知道我需要的这个依赖属于哪个依赖的下面,怎么查呢? IDEA中提供 ...

  7. 【Scala】01 基础了解

    Features 特性 1.基于JVM,完全兼容Java 2.同样具有跨平台,可移植,垃圾回收 3.比Java更加的面向对象[完全面向对象] 4.函数式编程 5.面向大数据处理,对集合容器框架有一定的 ...

  8. OpenCV计算机视觉学习(16)——仿射变换学习笔记

    如果需要其他图像处理的文章及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractic ...

  9. 设计和实现AI算法算法时有没有必要在代码中加注释,没有用必要在实现之前弄个UML图???

    问题如题: 设计和实现AI算法算法时有没有必要在代码中加注释,没有用必要在实现之前弄个UML图??? 今天看到一个博文: https://www.cnblogs.com/siyuanwai/p/154 ...

  10. oracle执行报错 ORA-01722: 无效数字

    1.背景 执行Oracle存储过程时报错:ORA-01722: 无效数字 2.错误描述 1.对于两个类型不匹配,一个数字类型,一个非数字类型的值进行赋值操作;2.两个类型不匹配的值进行比较操作,比如一 ...