当前位置: 首页 > news >正文

openGauss 之索引回表

一. 前言

​       在openGauss中如果表有索引信息,查询的谓词条件中又包含索引列,openGauss支持通过索引信息快速拿到需要访问元组的位置信息,然后直接到该位置上取出元组数据,称之为回表查询。如下所示,利用索引索引列id=55快速找到t111上对应元组的位置信息,然后通过位置信息拿到id为55的元组中所有列的数据。

    本文通过走读openGauss的代码了解openGauss是怎样实现回表查询的。

二.  Insert处理

​       要想实现能快速回表,那么insert时需要保存索引和物理表的位置信息关系。openGauss的insert的入口在ExecInsertT中,保存索引列与元组的位置信息代码流程如下所示:

ExecInsertTpTSelf = tableam_tops_get_t_self(result_relation_desc, tuple) // pTSelf保存着的是索引对应物理表元组位置信息relation->rd_tam_ops->tops_get_t_self(tup);HeapamTopsGetTSelfreturn tup->t_self   // 元组的物理表位置信息,即元组的t_selfExecInsertIndexTuplesindex_insert(..values, tupleid...)  // value为索引值,tupleid为对应物理表中元组位置信息btinsert_internal_bt_doinsert_bt_insertonpg_bt_pgaddtup(...itup...)  // 保存索引和其物理表中元组位置信息,itup为索引对应物理表元组位置信息

三.  回表查询

​       回表查询是在访问索引时,能通过索引的条件拿到元组的tid信息,然后到对应的物理表的tid位置上直接读取元组信息,代码入口在IndexNext,代码流程如下所示:

IndexNextscan_handler_idx_getnextindex_getnexttid = index_getnext_tid(scan, direction);  // 此函数将会拿到索引对应的物理表的元组地址DatumGetBool(FunctionCall2(procedure, PointerGetDatum(scan), Int32GetDatum(direction)));btgettuple_bt_gettuple_internalif (!BTScanPosIsValid(so->currPos))res = _bt_first(scan, dir);   // 首次扫描会将根据谓词条件二分法查找索引,并且保持满足谓词条件的起始地址和条数elseres = _bt_next(scan, dir);  // 初始化过之后,只要没有超过条数,直接返回下一条即可currItem = &so->currPos.items[so->currPos.itemIndex];scan->xs_ctup.t_self = currItem->heapTid;    // 回表元组的地址信息   IndexFetchTuple(scan)   // scan中保存有需要扫描元组的位置信息tidtableam_scan_index_fetch_tupleHeapamScanIndexFetchTupleheapam_index_fetch_tupleItemPointer tid = &scan->xs_ctup.t_self     // 对应上边索引返回的元组的地址信息heap_hot_search_buffer    // 拿到包含所有列完整的元组数据

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【Netty】netty中都是用了哪些设计模式
  • 端口安全老化细节
  • 软件测试之UI自动化测试
  • 被审稿人批得体无完肤?参考文献这样引用就对了!
  • 抠像拍照技术在展厅设计中的应用,实现了哪些新颖的互动体验?
  • uniapp vite3 require导入commonJS 的js文件方法
  • mysql可重复读不能解决幻读吗?
  • 安宝特科技 | AR眼镜在安保与安防领域的创新应用及前景
  • 实时地图+瞬移,黑神话地图工具来了
  • LLM模型:代码讲解Transformer运行原理
  • 快速排序的深入优化探讨
  • RedisCache存入redis的数据key为何name和id的分隔符是两个冒号::
  • 2024年高教社杯全国大学生数学建模竞赛A题思路(2024数学建模国赛A题思路)
  • 【Effective Java】多构造器参数使用构建器 (快速上手)
  • 【HuggingFace Transformers】OpenAIGPTModel源码解析
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • javascript 哈希表
  • Python连接Oracle
  • SOFAMosn配置模型
  • SQLServer之创建显式事务
  • Travix是如何部署应用程序到Kubernetes上的
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 码农张的Bug人生 - 见面之礼
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 深度学习在携程攻略社区的应用
  • 使用权重正则化较少模型过拟合
  • 在Unity中实现一个简单的消息管理器
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • 新年再起“裁员潮”,“钢铁侠”马斯克要一举裁掉SpaceX 600余名员工 ...
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • (1)STL算法之遍历容器
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (Matlab)使用竞争神经网络实现数据聚类
  • (二)PySpark3:SparkSQL编程
  • (每日一问)操作系统:常见的 Linux 指令详解
  • (生成器)yield与(迭代器)generator
  • (循环依赖问题)学习spring的第九天
  • (一) 初入MySQL 【认识和部署】
  • (转)项目管理杂谈-我所期望的新人
  • .libPaths()设置包加载目录
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .Net 知识杂记
  • .Net下使用 Geb.Video.FFMPEG 操作视频文件
  • .net中我喜欢的两种验证码
  • /etc/fstab和/etc/mtab的区别
  • @transactional 方法执行完再commit_当@Transactional遇到@CacheEvict,你的代码是不是有bug!...
  • @Transient注解
  • [ MSF使用实例 ] 利用永恒之蓝(MS17-010)漏洞导致windows靶机蓝屏并获取靶机权限
  • [Angular] 笔记 21:@ViewChild
  • [Angular] 笔记 6:ngStyle
  • [HNOI2008]水平可见直线