技术分享 | OceanBase 使用全局索引的必要性
2023-06-13 09:18:42 时间
OceanBase 从索引和主表的关系来讲,有两种索引:局部索引和全局索引。
局部索引等价于我们通常说的本地索引,与主表的数据结构保持一对一的关系。局部索引没有单独分区的概念,一般来讲,主表的分区方式决定局部索引的分区方式,也就是说假设主表有10个分区,那么对于每个分区来讲,都有一个对应的局部索引。
全局索引区别于局部索引,与主表数据结构保持一对多、多对多的关系,全局索引主要应用于分区表。对于分区表来讲,一个非分区全局索引对应主表的多个分区;一个分区全局索引也对应主表的多个分区,同时主表每个分区也对应多个全局索引的索引分区。
引入全局索引的目标就是弥补局部索引在数据过滤上的一些不足,比如避免分区表的全分区扫描,把过滤条件下压到匹配的表分区中。
针对查询过滤条件来讲,局部索引和全局索引的简单使用场景总结如下:
1. 带分区键的查询,适合用局部索引。这也是分区表设计的初衷,以过滤条件来反推分区表的设计。
比如语句:select * from p1 where id = 9; id 为分区键,可以直接定位到具体的表分区partitions(p9),仅需扫描一行记录。
<mysql:5.6.25:ytt>explain select * from p1 where id = 9\G
*************************** 1. row ***************************
Query Plan: ==================================
|ID|OPERATOR |NAME|EST. ROWS|COST|
----------------------------------
|0 |TABLE GET|p1 |1 |46 |
==================================
Outputs & filters:
-------------------------------------
0 - output([p1.id], [p1.r1], [p1.r2]), filter(nil),
access([p1.id], [p1.r1], [p1.r2]), partitions(p9)
1 row in set (0.005 sec)
2. 不带分区键的查询有两个考虑方向,主要在于能否克服全局索引的缺点:全局索引势必会带来查询的分布式执行!
(1)表的并发写不大,可以考虑用全局索引。
(2)表的并发写很大,用全局索引与否就有待商榷, 可以根据当前的业务模型做个压力测试,取一个折中点。
比如以下语句, 全局索引idx_r2_global基于非分区字段r2,执行计划如下:算子1需要去底层各个节点分布式扫描(DISTRIBUTED TABLE SCAN)。
<mysql:5.6.25:ytt>explain select * from p1 where r2 = 30\G
*************************** 1. row ***************************
Query Plan: =============================================================
|ID|OPERATOR |NAME |EST. ROWS|COST|
-------------------------------------------------------------
|0 |TABLE LOOKUP |p1 |101 |395 |
|1 | DISTRIBUTED TABLE SCAN|p1(idx_r2_global)|101 |48 |
=============================================================
...
3. 对于需要在非主键、非分区键的字段上建立唯一索引的业务来讲,可以有两个考虑方向:
(1)给这个字段创建局部索引,但是需要带上完整的分区键。 不推荐这种方式,一来是需要更改过滤条件,增加分区键;二来增加索引本身的数据冗余。
比如在MySQL租户下创建这样的索引会报错:
<mysql:5.6.25:ytt>create unique index udx_r1 on p1(r1) local;
ERROR 1503 (HY000): A UNIQUE INDEX must include all columns in the table's partitioning function
如果创建本地索引,则需要加上完整分区键:
<mysql:5.6.25:ytt>create unique index udx_r1_local on p1(r1,id) local;
Query OK, 0 rows affected (3.012 sec)
(2)给这个字段创建全局索引,不需要带上完整的分区键。 强烈推荐的方式!
<mysql:5.6.25:ytt>create unique index udx_r1_global on p1(r1) global;
Query OK, 0 rows affected (1.950 sec)
相关文章
- 技术阅读摘要 - 4.闲谈晋升
- Gartner发布2023年十大战略技术趋势
- 网络工程师 | IT通用技术专题-存储
- MySQL实现大数据量分表分页技术(mysql分表分页)
- Oracle两列相减技术实现(oracle两列相减)
- Oracle数据库中的几种索引技术探究(oracle几种索引)
- Linux文件加锁保护技术(linux文件锁)
- Oracle存储过程中的运算技术研究(oracle存储过程运算)
- 基因“黑客”欲用CRISPR技术治疗宠物遗传病,却收到FDA警告
- Oracle的索引压缩技术及应用(oracle压缩索引)
- 降低游戏延迟!腾讯《CFHD》将支持NVIDIA Reflex技术
- 引擎MSSQL索引缓存引擎优化性能的突破性技术(mssql 索引缓存)
- MSSQL索引:优化空间占用技术(mssql索引占用空间)
- 优化Oracle数据库性能关联加索引技术分析(oracle 关联加索引)
- Redis实现的限流技术善用计数(redis限流次数)
- Redis锁自动续期技术实现分析(redis锁自动续期)
- Redis极大加速钙化技术效果引发关注(redis钙化)
- Oracle存储过程返回值技术指南(oracle sp返回值)
- 垂直扩展的Oracle RIC新技术领先优势(oracle ric)
- Redis槽位技术未来的NoSQL分布式数据库(redis槽位值)