关于OceanBase MySQL 模式中全局索引 global index 的常见问题

news2024/12/23 11:31:18
在OceanBase的问答区和开源社区钉钉群聊中,时常会有关于全局索引 global index的诸多提问,因此,借这篇博客,针对其中一些普遍出现的问题进行简要的解答。

什么是 global index ?

由于 MySQL 不具备 global index 的概念,因此这一问题会经常被社区版用户提及。就在前几天,就要人询问下面这个语法的意义。

create table part_test_tbl(
  id int,
  age int,
  unique key uk_id_idx(id) partition by hash(id),
  key age_idx(age) partition by hash(age));

这个问题的答案可以直接照搬 OB 官网上全局索引的概念:全局索引的创建规则是在索引属性中指定 GLOBAL 关键字。与局部索引相比,全局索引最大的特点是全局索引的分区规则跟表分区是相互独立的,全局索引允许指定自己的分区规则和分区个数,不一定需要跟表分区规则保持一致。

为什么要有 global index ?

在关系性数据库中,索引通常被组织成一颗 B+ 树的形式,叶子节点按照键值的大小被有序存放,索引的键值跟主表上的数据一一对应,当用户指定索引条件访问数据的时候,可以迅速的通过搜索 B+ 树上的对应关系,快速定位到被访问到的数据在主表中的位置。

1705643610

当主表数据被拆分成多个分片的时候(在 OB 中叫分区表),索引应该怎么拆分?一个思路是让索引跟主表一起拆分,拆分后的索引只检索当前分区中的部分数据,这样的索引我们一般称为本地索引(Local Index,MySQL 就只支持这种索引)。在 OB 中要创建这样的索引也很简单,只需要在语句最后指定一个 local 关键字即可。这样的索引有什么缺点呢?

首先第一个缺点就是我们的查询必须要指定分区键,否则,数据库将不知道你需要检索的数据位于哪个分片中,只能枚举出所有的数据分片,让查询效率变低。这里我们展示了一个这样的例子(主表 employ 是分区表,分区键是 emp_id),如果查询中的过滤条件没有指定主表的分区键 emp_id,从执行计划的红框部分可以看出来,数据库就会扫描所有的数据分片。

1705643623

另一个缺点就是由于本地索引是创建在数据分片内部,因此无法保证索引键值的全局唯一性,比如我们下边的这个例子中,本地索引的两部分都可能出现 'Edward' 这个重复键值,因此数据库要求要创建带唯一性约束的本地索引必须要指定数据分片的分区键。

1705643630

为了解决本地索引的这些不好的用户体验,OceanBase 数据库在 MySQL 模式下又推出了一种新的索引形式,那就是全局索引(Global Index),它和本地索引(Local Index)的本质区别是:全局索引的索引结构并不跟主表的分片信息一一对应,它们数据的分片位置信息是各自独立的。同时呢,一个索引键值可能会对应到不同的主表分片当中,例如在我们右边展示的这个索引结构中,索引键值 1,2,5 都同时对应了两个不同分区里的数据,因此在使用全局索引进行数据检索的时候,我们不再需要指定分区键,同时由于全局索引的索引结构是独立于主表的,索引键值的全局唯一性在这里也可以很好的被保证。

1705643639

要创建一个全局索引也很简单,只需要我们在创建索引的语法后面指定一个 global 关键字就好了(如果索引后面有分区信息会被默认当作 global index,否则会被默认当作 local index)。

create table t1(c1 int, c2 int, c3 int);

create index idx1 on t1(c1);

create index idx2 on t1(c2) global;

create index idx3 on t1(c3) partition by hash(c3);

show create table t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `c1` int(11) DEFAULT NULL,
  `c2` int(11) DEFAULT NULL,
  `c3` int(11) DEFAULT NULL,
  KEY `idx1` (`c1`) BLOCK_SIZE 16384 LOCAL,
  KEY `idx2` (`c2`) BLOCK_SIZE 16384 GLOBAL,
  KEY `idx3` (`c3`) BLOCK_SIZE 16384 GLOBAL
 partition by hash(c3)
(partition p0));

什么场景适合使用 global index ?

刚才我们了解了全局索引的两个好处,那么在 OceanBase 这样的分布式数据库中,是不是应该无条件使用全局索引呢?由于全局索引可能会出现跨节点的数据访问,因此数据检索过程中,RPC 的代价是无法忽略的,因此并不是所有情况下用全局索引都比本地索引表现更好。那哪些场景我们推荐使用全局索引呢?

    1. 如果索引键能够覆盖用户检索的全部字段,这种情况下,索引检索不需要再去访问主表,这种情况全局索引代价会比本地索引更小。
    2. 如果检索的数据量比较少(100行以内),回表所产生的 RPC 代价也会较小,这种情况下,我们也推荐使用全局索引。(前两天听到几个经验值:1 秒钟可以让 100 万行数据 I/O,或者让 10 万行 local index 回表,或者让 1 万行 global index 回表。)
    3. 如果需要保证索引键满足唯一性约束,并且索引键不包含分区键信息,这种情况下,由于本地索引自身的唯一性缺陷,也只能选择全局索引。

总的来说,全局索引相比于本地索引实现会更加复杂,尤其在分布式数据库中,只有少数的商业数据库支持这种索引形式,但是它对用户的使用约束更小,体验也会更好。

其他几个常见问题

为什么主键索引不能设置成 global 属性

OceanBase 数据库的表目前都是索引组织表(Index Organized Table,简称 IOT 表),暂时还没有支持堆表。索引组织表是一种数据库表的存储方式,它的特点是根据表的主键索引来组织数据,而不是按照数据的物理顺序来组织。因为每张表都是根据主键索引来组织的,所以主键和主表的组织形式一定是一致的,不能设置成 global 属性。

顺带一提,OceanBase 中的无主键表其实也有隐藏主键,是个自增列,column id 为 1, column name 叫 __pk_increment,有兴趣的同学可以去查查 oceanbase.__all_column 看一下。

为什么分区表的分区键一定要被包含在本地唯一索引和主键索引里?

OceanBase 官网文档上说:如果需要在分区表上创建局部分区唯一索引( Local Partitioned Unique Index ),则该索引键需要包含主表的分区键,而对于全局分区唯一索引( Global Partitioned Unique Index )并没有这个限制。

create table t1(c1 int unique key, c2 int) partition by hash(c2);
ERROR 1503 (HY000): A UNIQUE INDEX must include all columns in the table's partitioning function

create table t1(c1 int primary key, c2 int) partition by hash(c2);
ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function

刚才上面介绍 global index 的时候提到了:唯一索引上数据的唯一性检查是只在当前分区做的,如果唯一索引不包含全部分区键,例如让 create table t1(c1 int unique key, c2 int) partition by hash(c2); 执行成功的话,主表上的数据可能会是:

c1c2
11
12
21
22
31
32

   这时第一个分区的数据是:(在这个分区中 c1 是满足唯一性的,唯一性检查会成功)

c1c2
11
21
31

   第二个分区的数据是:(在这个分区中 c1 也是满足唯一性的,唯一性检查也会成功)

c1c2
12
22
32

这就会出现:所有分区在对 c1 做唯一性检查时都成功了,数据库认为 c1 列已经满足了唯一性,但实际上 c1 列的数据却并没有满足唯一性。主键同理。当然,MySQL 和 Oracle 数据库也有相同的要求和限制。如果唯一索引被打上了 global 的属性,就不会再和主表使用一样的分区规则去进行分区,自然也就没有这个唯一性检查出错的问题了。

   如果大家对 global index 还有什么其他问题,可以在博客下面留言,我们一起学习和探讨~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2119345.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用TCP编程实现FTP功能

模拟FTP核心原理:客户端连接服务器后,向服务器发送一个文件。文件名可以通过参数指定,服务器端接收客户端传来的文件(文件名随意),如果文件不存在自动创建文件,如果文件存在,那么清空…

uboot源码分析uboot启动流程,uboot-CMD命令调用关系

uboot的最终目的是引导启动内核加载系统,根据这个线索我们可以首先找到uboot引导内核的main函数,查看系统引导的执行跳转的函数 main_loop。 下面对uboot函数的调用关系和主要调用函数进行分析。 一、uboot函数调用关系梳理 函数调用如下: …

Ollama 本地运行大模型(LLM)完全指南

文章介绍了 Ollama 本地运行大模型(LLM)的方方面面, 包括安装运行、对话、自定义模型、系统提示配置、调试、开发、存储、如何作为服务、OpenAI 的兼容等。 这一年来,我已经习惯了使用线上大模型 API 来工作,只要网络…

2025毕业设计免费指导!!

本人专注于Android/java/PHP/Python/人工智能/数据库/微信小程序技术等领域的开发,以及有好几年的计算机毕业设计方面的实战开发经验和技术积累;尤其是在图像识别、网站开发和微信小程序的开发,很是熟悉和了解;本人也是多年的全栈…

DevOps实现CI/CD实战(六)- Jenkins集成k8s

十、 Jenkins集成k8s Jenkins在集成K8s之前,需要搭建k8s集群,具体搭建步骤,完整笔记 https://github.com/ITenderL/ITenderL.github.io/tree/main/docs/DevOps, 包括完整的DevOps的笔记。 1. 准备部署的yml文件 pipeline.yml …

祝福在茶礼丨酒茶香充满东方古韵特色的中秋礼盒,太惊艳了

中国是礼仪之邦,礼尚往来更是普通不过。象征东方古韵的茶礼成为现代送礼热门,尤其是逢年过节茶礼氛围更是浓郁,跃居礼单榜首。 中秋节作为团圆之节,送礼肯定少不了!送茶礼的这几个理由你一定要知道! 送茶即…

【动手学深度学习】06 矩阵计算(个人向笔记)

标量导数 这个比较简单,就是直接求导 亚导数 举了两个例子 梯度 下面是当 y 和 x 分别为向量和标量时求导的结果。一个为向量,一个为标量则结果为向量。两个都为向量结果为矩阵,两个都为标量结果为标量 当 y 为标量,x 为列…

关于腾讯IM消息ID不统一的问题?服务端的MsgKey和前端的msgID不一样

角色>前端:web、小程序、客户端(ios、安卓);服务端;腾讯IM; 1、背景 IM消息ID不一致,本地没有缓存历史数据,导致在调用腾讯sdk方法时,id不一致报错问题 2、调研目的…

MySQL进阶篇4 - 锁

五、锁 5.1 概述 介绍 分类 5.2 全局锁 介绍 红色代表不可执行的操作,绿色代表可执行的操作 # mysqldump 是 MySQL 提供的数据备份的命令演示 # 如果想进行全库的逻辑备份,那么就需要在逻辑备份之前 # 手动的加上全局锁 flush tables with read …

flask下https教程

一、定义 linux 下flask https 协议 二、实现 linux 下flask https 协议 生成SSL证书和密钥文件。您可以使用工具如openssl来生成自签名SSL证书和密钥文件。运行以下命令生成证书和密钥文件: openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout…

HCIE和CCIE,哪个含金量更高点?

在现在内卷的大环境下,技术岗可谓人人自危,也因此各种认证的重视程度直线升高。 特别是华为认证的HCIE和思科认证的CCIE,它们都代表着网络技术领域的顶尖水平。 但面对这两个高含金量的认证,不得不让人问出这个问题:同…

找到办法了!一个站点,搞定所有访问权限需求

在知识库的构建与管理过程中,如何平衡信息的公开与私密性始终是一大挑战。传统方法往往需要建立多个具有不同访问权限的站点,操作繁琐且难以维护。尤其当企业需同时向公众和内部成员提供知识文章时,这一问题尤为突出。用户频繁反馈&#xff0…

振弦式渗压计安装流程全面指南

在大坝安全监测体系中,振弦式渗压计作为关键设备之一,承担着监测大坝内部渗流压力变化的重任。其安装质量直接关系到监测数据的准确性和大坝安全的评估。因此,制定一套科学、精细的安装流程,对于确保渗压计的正常运行和延长使用寿…

什么是生成式 AI?

人工智能 (AI) 通过使用机器学习与环境交互并执行任务来模仿人类行为,而无需明确指示要输出的内容。 生成式 AI 描述 AI 中用于创建原创内容的一类功能。 人员通常与聊天应用程序中内置的生成式 AI 交互。 此类应用程序的一个常见示例是 Microsoft Copilot&#xf…

Telephony STK 域选

在场测过程中,经常遇到STK功能不生效,点击STK会出现无响应的问题. 一般需要对比DUT和REF来确认问题所在。一般情况下,出现类似问题需要check是否域选是一致的。 测试机 对比机 对比机为展锐平台会出现弹框情况,从Log看,相关业务进行了报错回落,从IMS业务回落到了…

基于spring的博客系统(一)

通过前⾯课程的学习, 我们掌握了Spring框架和MyBatis的基本使⽤, 并完成了图书管理系统的常规功能 开发, 接下来我们系统的从0到1完成⼀个项⽬的开发; 1. 项⽬介绍 使⽤SSM框架实现⼀个简单的博客系统 共5个⻚⾯ 1. 用户登录 2. 博客发表⻚ 3. 博客编辑⻚ 4. 博客…

【Java算法】模拟

🔥个人主页: 中草药 🔥专栏:【算法工作坊】算法实战揭秘 🧣 一.模拟算法 模拟算法和传统的算法有一些不同之处,更多的是对题目要求的理解,通过代码的方式去模拟实现一道题目在现实中的实现方法…

接口基础知识4概念纠正与补充说明

​接口基础知识4 1 请求方法的幂等性 幂等性的理解是没有问题的。但是请求方法和幂等性没有直接的关联。 在 REST API 设计中,幂等性非常重要,因为它保证了在重复请求的情况下,资源的状态始终保持一致,不会因为重复请求而发生副…

量化交易backtrader实践(一)_数据获取篇(1)_数据准备

我们需要使用backtrader来做量化交易回测,先解决一些前置问题: 需要回测哪几支股票,或者即时选取股票即时选取股票以什么形式,代码还是名称这些数据的格式是怎么样的,backtrader如何接收 在解决这些前置问题的过程中…

如何抽取一个特定页面从devExpress的例程集合中

https://download.csdn.net/download/haoyujie/89729356https://download.csdn.net/download/haoyujie/89729356相关资源。 devExpress界面库的例程的设计是有必要来吐槽的。其紧耦合和大捆绑,我认为是devExpress很重要的不友好,导致可用性差和学习曲线…