首页 > 数据库 >【YashanDB知识库】绑定参数,同一个sql多个执行计划的问题

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

时间:2024-07-26 10:07:57浏览次数:9  
标签:YashanDB attr 知识库 MZONE pool sql POOL SIZE

问题现象

同一个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,attr,知识库,MZONE,pool,sql,POOL,SIZE
From: https://www.cnblogs.com/YashanDB/p/18324748

相关文章

  • mysql 优化
    ##计算shmall和shmmax值memTotal=$(grepMemTotal/proc/meminfo|awk'{print$2}')totalMemory=$((memTotal/2048))shmall=$((memTotal/4))if[$shmall-lt2097152];thenshmall=2097152fishmmax=$((memTotal*1024-1))if["$shmmax"-lt429......
  • 基于SpringBoot+Vue的人事系统 毕业设计 springboot+Vue+mysql
    介绍本人事系统基于SpringBoot和Vue框架开发,旨在为企业提供高效、便捷、准确的人事管理解决方案。通过现代化的技术手段,实现了人事数据的集中管理、流程的自动化处理以及信息的实时共享,从而提高企业的人事管理效率和决策科学性。技术栈后端技术栈:Springboot+Mysql+Maven......
  • 运维文档:MySQL 数据库备份与恢复
    运维文档:MySQL数据库备份与恢复1.概述本文档旨在提供MySQL数据库备份与恢复的详细步骤和操作指南,以确保数据的安全性和可恢复性。2.备份方案2.1备份类型逻辑备份:备份数据库中的数据文件,包括数据表、视图、存储过程等。物理备份:备份整个数据库实例,包括数据文件、日......
  • 如何安装mysqlclient 1.4.6? (Python 3.6)MacO?
    我安装pipinstallmysqlclient==1.4.6--no-cache-dir但是出现错误:ld:library'ssl'notfoundclang:error:linkercommandfailedwithexitcode1(use-vtoseeinvocation)error:command'clang'failedwithexitstatus......
  • MySQL查询性能优化
    避免使用SELECT*:只选择必要的列可以减少数据传输量和处理时间。避免使用OR和NOTIN:使用OR和NOTIN会导致全表扫描,影响查询性能。使用LIMIT分页:使用LIMIT分页可以避免一次性返回大量数据‍。使用EXPLAIN查看执行计划:可以通过查看执行计划了解SQL的执行情况。优化WHERE条件:尽可......
  • SQL-获取某个库的指定表信息、指定表的字段信息
    获取指定表字段获取指定前缀的表名(只能查看,无法拼接字段):SHOWTABLESLIKE'ck_cus%';获取指定前缀的表名,并以逗号分隔拼接:SELECTgroup_concat(TABLE_NAME)FROMINFORMATION_SCHEMA.TABLESWHERETABLE_NAMELIKE'ck_%';获取指定前缀的表名,拼接生成特定SQL语句:SELECT......
  • SQL-数据按月、日统计
    按月统计方案1:SELECTDATE_FORMAT(START_TIME_,'%Y-%m')ASmonth,COUNT(*)AScountFROMACT_HI_PROCINSTWHERESTART_TIME_>='2024-06-27'ANDSTART_TIME_<'2024-08-08'--替换为你的日期范围GROUPBYDATE_FORMAT(START_TIME_,......
  • 【PostgreSQL教程】PostgreSQL 创建数据库
    博主介绍:✌全网粉丝20W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。感兴趣的可以先......
  • MySQL的查询优化思路
    目录前言解决方案减少查询SQL优化索引优化减少锁避免大事务扩容硬件升级前言一般的系统中,数据库往往都是性能瓶颈。在一个系统中,数据库被使用的频率很高,因为几乎所有的应用程序都需要与数据库交互来读取或写入数据。所以一旦数据库的响应慢,负载突增,则会大大影响系......
  • MySQL Sink 是否需要主键
    需要主键的情况:更新和删除操作:如果你希望MySQL表能够正确处理更新和删除操作,那么表中需要定义主键。主键用于唯一标识每一行数据,这样当Flink发送撤回消息(删除操作)或添加消息(更新操作)时,MySQL能够准确地找到并更新或删除对应的记录。数据一致性:主键有助于确保数据的一致性......