同样的命令,为什么一个是全局索引,一个不是全局索引?

图片

以上是在V4.6.0版本MySQL租户下的实验。

请教大家:
1 为什么案例一,创建的索引是全局索引,因为is_global_index=true。

 2 为什么案例二,创建的索引不是全局索引,因为is_global_index=false。

3 另外, create index i2 on t2(c2) 和 create index i2 on t2(c2) GLOBAL, 创建的都是全局索引 ?

8 个赞

@论坛小助手 解答下

问题解析与回答

根据您提供的信息,您提到的两个案例中创建了不同的索引,并且通过 explain 语句查看了这些索引在查询计划中的表现。以下是针对您的三个问题的详细解答:

1. 为什么案例一,创建的索引是全局索引 (is_global_index=true)?

  • 在案例一中,表 t2 被定义为一个分区表,使用 PARTITION BY HASH(c1) PARTITIONS 4; 进行了分区。
  • 创建索引时明确指定了 GLOBAL 关键字:create index i2 on t2(c2) GLOBAL;
  • 对于分区表,在创建索引时指定 GLOBAL 将使索引成为一个全局索引。这意味着索引将跨越所有分区,并且在查询时能够提供更高效的访问路径。

因此,当您在分区表上创建全局索引时,explain 输出显示 is_global_index=true

2. 为什么案例二,创建的索引不是全局索引 (is_global_index=false)?

  • 在案例二中,表 t2 没有被定义为分区表,即是一个普通的表。
  • 即便创建索引时使用了 GLOBAL 关键字:create index i2 on t2(c2) GLOBAL;,但因为该表本身不是分区表,所以这里的 GLOBAL 关键字实际上没有意义。
  • 非分区表上的索引默认都是局部索引(local index),即使指定了 GLOBAL,也不会改变其本质。

因此,对于非分区表,即使尝试创建全局索引,explain 输出仍会显示 is_global_index=false

3. 另外,create index i2 on t2(c2)create index i2 on t2(c2) GLOBAL,创建的都是全局索引吗?

  • 对于分区表而言,create index i2 on t2(c2) GLOBAL; 会创建一个全局索引 (is_global_index=true)。
  • 如果不指定 GLOBAL,则默认情况下创建的是局部索引 (is_global_index=false)。
  • 对于非分区表,无论是否指定了 GLOBAL,最终创建的都将是局部索引 (is_global_index=false)。

总结来说,GLOBAL 关键字只有在分区表上创建索引时才真正起到作用,表示这是一个全局索引。而对于非分区表,它不会影响索引类型,结果依然是局部索引。

希望以上解释能帮助您理解不同情况下索引类型的差异。如果您还有其他疑问,请随时提问!

详情请参考:

  1. 常见的 SQL 调优方式
8 个赞

论坛小助手的回答很完美,学习了。

建表不一样,一个是分区表,一个是普通表。

对于index问题,除了文中提到的方法,还可以考虑GLOBAL和is的结合使用。

学会了呀

业务需要啥索引就建啥索引

t1表是一个普通表,给它创建了一个分区索引,这个分区索引有p0、p1、p2这三个分区,那么这个分区索引的三个分区p0、p1、p2,是和主表数据绑定在一起的吗?他们是被存储在同一个observer节点里吗? @论坛小助手 解答下

根据您提出的问题,我们需要明确几个关键点来回答您的疑问。首先,OceanBase 的局部索引(也称为分区索引)与主表数据的关系以及它们在存储节点上的分布情况。基于文档片段中的信息,可以得出以下结论:

  1. 局部索引的数据绑定

    • 局部索引是针对单个分区上的数据创建的索引,因此局部索引的索引键值跟表中的数据是一一对应的关系,即局部索引的一个分区一定对应到一个表分区,它们具有相同的分区规则。
    • 由于局部索引和主表使用了相同的分区策略,每个分区的索引数据会与对应的主表分区数据保持一致。这意味着 p0、p1、p2 这三个分区的索引数据将会分别与主表中相应的分区数据关联在一起。
  2. 局部索引的存储位置

    • 文档片段7中提到,局部索引与单表或者分区表最小子分区绑定在一起,不会在 OceanBase 数据库系统租户中创建额外的分区记录,所有基于局部索引的 SQL 基本都是本地执行。
    • 对于局部索引来说,它通常会和对应的主表分区数据存储在同一个 OBServer 节点上。这是为了保证查询时能够减少跨节点通信带来的性能开销。因此,按照默认行为,p0、p1、p2 分区的索引应该会与其各自对应的主表分区数据存储在同一 OBServer 节点上。

综上所述,对于普通表 t1 创建的局部索引,其各个分区 p0、p1、p2 是和主表数据绑定在一起的,并且它们会被存储在同一个 OBServer 节点中。这种设计旨在提高查询效率,尤其是在处理大数据量时,避免了跨节点访问索引数据所带来的额外开销。但请注意,在某些特定情况下(例如集群内重新平衡或手动调整),可能会出现局部索引分区与主表分区不在同一物理节点的情况。不过,这种情况并不常见,并且通常需要人工干预才会发生。

希望以上解释能帮助解答您的疑问。如果还有其他问题,请随时告知!

详情请参考:

  1. 索引概述
  2. 分区索引
  3. OceanBase 数据库性能的影响因素
  4. 全局索引
  5. 租户内均衡
  6. 集群管理 FAQ
  7. SQL 路由
  8. 局部索引

@论坛小助手 回答下

您好!根据您的问题,我将详细解答关于局部索引(分区索引)在 OceanBase 中的存储和分布情况。

问题解析

您提到 t1 表是一个普通表,并且为其创建了一个分区索引,该索引有 p0p1p2 这三个分区。您想了解这些分区索引是否与主表数据绑定在一起,以及它们是否存储在同一个 OBServer 节点中。

详细解答

1. 局部索引的数据绑定

  • 局部索引:局部索引是针对单个分区上的数据创建的索引。每个局部索引分区与对应的表分区是一一对应的。
  • 绑定关系:局部索引的各个分区(如 p0p1p2)与主表的相应分区数据是绑定在一起的。这意味着每个局部索引分区只包含对应表分区的数据。

2. 存储位置

  • 默认行为:在默认情况下,局部索引的各个分区会与对应的主表分区数据存储在同一个 OBServer 节点上。这是为了提高查询效率,减少跨节点通信带来的性能开销。
  • 分区分布:如果主表的 p0 分区数据存储在某个 OBServer 节点上,那么 p0 分区的局部索引数据也会存储在同一个 OBServer 节点上。同样的逻辑适用于 p1p2 分区。

3. 特殊情况

  • 集群重新平衡:在某些特殊情况下,例如集群进行重新平衡或手动调整时,可能会出现局部索引分区与主表分区不在同一物理节点的情况。但这种情况并不常见,通常需要人工干预才会发生。
  • 副本策略:OceanBase 支持多副本策略,确保数据的高可用性。每个分区的副本可以分布在不同的 OBServer 节点上,以提高系统的容错能力。但主副本和局部索引的主副本通常会保持在同一节点上。

总结

  • 数据绑定:局部索引的各个分区 p0p1p2 与主表的相应分区数据是绑定在一起的。
  • 存储位置:默认情况下,局部索引的各个分区会与对应的主表分区数据存储在同一个 OBServer 节点上。
  • 特殊情况:在集群重新平衡或手动调整的情况下,可能会出现局部索引分区与主表分区不在同一物理节点的情况,但这并不常见。

希望以上解释能帮助您理解局部索引在 OceanBase 中的存储和分布情况。如果您还有其他问题,请随时提问!

t1表是一个普通表,给它创建了一个全局分区索引,这个全局分区索引有p0、p1、p2这三个分区,那么这个全局分区索引的三个分区p0、p1、p2,是和主表数据绑定在一起的吗?他们是被存储在同一个observer节点里吗? @论坛小助手

您好!根据您的问题,您提到 t1 表是一个普通表,并且为其创建了一个全局分区索引,该索引有 p0、p1、p2 这三个分区。您想了解这些全局分区索引的分区是否与主表数据绑定在一起,以及它们是否存储在同一个 OBServer 节点中。

详细解答

  1. 全局分区索引的数据绑定

    • 独立分区定义:全局索引拥有自己独立的分区定义,不需要跟主表一样。也就是说,全局索引的分区可以有自己的分区规则,不一定与主表的分区规则相同。
    • 不绑定:由于全局索引和主表的分区规则可以不同,因此全局索引的各个分区(如 p0、p1、p2)并不一定与主表的数据绑定在一起。每个全局索引分区可能对应主表的多个分区中的数据。
  2. 存储位置

    • 独立存储:全局索引的各个分区(如 p0、p1、p2)并不一定会与主表的数据存储在同一个 OBServer 节点上。由于全局索引有独立的分区规则,其索引数据和主表数据可能会分布在不同的节点上。
    • 跨节点通信:由于全局索引的分区规则和主表的分区规则不一定相同,在分布式环境中,查询时可能会引入跨节点的 RPC 代价和分布式事务的代价。例如,当主表的分区和全局索引的分区不在同一个物理位置上时,TABLE SCAN 算子执行全局索引表扫描时就会包含一次 RPC 操作到远端机器上去获取主表数据。
  3. 文档依据

    • 片段5集群管理 FAQ → 存储 FAQ → 在 OceanBase 数据库中,局部索引与全局索引在实现上的区别是什么?

      • 局部索引:和单表或者分区表最小子分区绑定在一起,不会在 OceanBase 数据库系统租户中创建额外的分区记录,所有基于局部索引的 SQL 基本都是本地执行。
      • 全局索引:需要在 OceanBase 数据库系统租户中创建额外的一个分区记录,可以理解为另外一张表,占用额外的分区配额。全局索引可以有自己的分区策略,Locality 也不与主表绑在一起,即使是单表,全局索引也可以与主表分别存储在不同的节点上,当然这样也更容易使 SQL 成为分布式 SQL。
    • 片段6OceanBase 数据库性能的影响因素 → 资源分配 → 局部索引和全局索引 → 全局索引

      • 全局索引不再和主表的分区保持一对一的关系,而是将所有主表分区的数据合成一个整体来看,索引中的一个键可能会映射到多个主表分区中的数据(当索引键有重复值时)。全局索引可以定义自己独立的数据分布模式,既可以选择非分区模式也可以选择分区模式;在分区模式中,分区的方式既可以和主表相同也可以和主台不同。

总结

  • 数据绑定:全局分区索引的各个分区 p0、p1、p2 不是与主表数据绑定在一起的。全局索引有自己独立的分区规则。
  • 存储位置:全局分区索引的各个分区 p0、p1、p2 不一定与主表的数据存储在同一个 OBServer 节点上。它们可以分布在不同的节点上,从而可能引入跨节点通信的开销。

希望以上解释能帮助您理解全局分区索引在 OceanBase 中的存储和分布情况。如果您还有其他问题,请随时提问!

详情请参考:

  1. 全局索引
  2. 分区索引
  3. 索引概述
  4. 集群管理 FAQ
  5. OceanBase 数据库性能的影响因素
  6. 租户内均衡
  7. 索引设计

又学到了,非分区表默认都是局部索引,指定Global也不行,难道非分区表不能是全局索引么

读完关于同样的命令,为什的内容,感触很多。

图片
@论坛小助手 解答一下

您好!根据您提供的 explain 语句的输出,我将帮助您理解查询计划的结果,并解答您的问题。

问题解析

您创建了一个表 t1,并执行了一个 explain 语句来查看查询 select * from t1 order by c1 的执行计划。从 OCR 提取的内容来看,查询计划显示了一些关键信息。

详细解答

  1. 表定义

    create table t1(c1 int primary key, c2 int, c3 int, c4 int);
    
  2. 查询和解释

    explain select * from t1 order by c1;
    
  3. 查询计划输出

    +----------------------------------------------------+
    | output([t1.c1], [t1.c2], [t1.c3], [t1.c4])          |
    | access([t1.c1], [t1.c2], [t1.c3], [t1.c4]),         |
    | partitions(p0, p1, p2),                            |
    | is_index_back=false,                               |
    | range_key([t1.c1]),                                |
    | range(MIN, MAX)                                    |
    | TABLE RANGE SCAN,                                  |
    | range(MIN, MIN, MIN, MAX, MAX, MAX)                |
    +----------------------------------------------------+
    

解读查询计划

  1. 输出列

    • output([t1.c1], [t1.c2], [t1.c3], [t1.c4]):查询将返回表 t1 中的所有列 c1, c2, c3, c4
  2. 访问列

    • access([t1.c1], [t1.c2], [t1.c3], [t1.c4]):查询会访问表 t1 中的所有列 c1, c2, c3, c4
  3. 分区

    • partitions(p0, p1, p2):表 t1 有三个分区 p0, p1, p2
  4. 索引使用情况

    • is_index_back=false:查询没有使用索引进行回表操作(即没有通过索引获取数据)。
  5. 范围键

    • range_key([t1.c1]):查询按 c1 列进行排序。
    • range(MIN, MAX):查询的范围是从最小值到最大值,即全表扫描。
  6. 表扫描方式

    • TABLE RANGE SCAN:查询对表进行了全表扫描。
    • range(MIN, MIN, MIN, MAX, MAX, MAX):具体的扫描范围是全表范围,表示从最小值到最大值的所有数据。

总结

  • 查询类型:这是一个全表扫描(TABLE RANGE SCAN),因为没有使用任何索引。
  • 分区:表 t1 有三个分区 p0, p1, p2,查询将涉及所有这些分区。
  • 排序:查询按 c1 列进行排序,但没有使用索引来加速这个排序操作,而是进行了全表扫描。

建议

如果您希望优化这个查询,可以考虑以下几点:

  1. 创建索引:如果 c1 列经常用于排序或过滤,可以考虑在 c1 列上创建一个索引,以提高查询性能。

    create index idx_c1 on t1(c1);
    
  2. 检查分区策略:确保分区策略适合您的查询需求。如果分区策略不合理,可能会导致不必要的跨分区操作。

希望以上解释能帮助您理解查询计划的结果。如果您还有其他问题,请随时提问!

详情请参考:

  1. UNCOMPRESSED_LENGTH
  2. UNCOMPRESS
  3. UPPER
  4. MIN
  5. FORMAT
  6. JSON_OBJECTAGG
  7. JSON_ARRAYAGG
  8. INNER JOIN
  9. FORMAT_BYTES
  10. CREATE USER