PolarDB-X性能优化之全局二级索引的使用

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 使用全局索引将join操作下推至存储节点

1 测试用表及定义

1) product表及定义

MySQL [test]> show create table product;

CREATE TABLE `product` (

       `id` bigint(20) NOT NULL,

       `name` varchar(20) DEFAULT NULL,

       `producer` bigint(20) DEFAULT NULL,

       `type` varchar(10) DEFAULT NULL,

       PRIMARY KEY USING BTREE (`id`),

       GLOBAL INDEX `g_i_emp_id` (`producer`) PARTITION BY KEY (`producer`) PARTITIONS 2,

       GLOBAL INDEX `g_i_emp_id_name` (`producer`) COVERING (`name`) PARTITION BY KEY (`producer`) PARTITIONS 2,

       KEY `_local_g_i_emp_id` (`producer`),

       KEY `_local_g_i_emp_id_name` (`producer`)

) ENGINE = InnoDB DEFAULT CHARSET = utf8

PARTITION BY KEY(`id`)

PARTITIONS 3;  

2)emp表及定义

MySQL [test]> show create table emp;

CREATE TABLE `emp` (

       `id` bigint(11) NOT NULL AUTO_INCREMENT,

       `name` varchar(255) DEFAULT NULL,

       `dept_no` int(11) DEFAULT NULL,

       `salary` bigint(10) DEFAULT NULL,

       PRIMARY KEY (`id`)

) ENGINE = InnoDB AUTO_INCREMENT = 100005 DEFAULT CHARSET = utf8

PARTITION BY KEY(`id`)

PARTITIONS 2;


2 emp表所在的表组内表的情况

MySQL [information_schema]> select   TABLE_SCHEMA,TABLE_GROUP_NAME,TABLE_NAME from TABLE_DETAIL where table_group_name like 'tg1';

+--------------+------------------+------------+

| TABLE_SCHEMA | TABLE_GROUP_NAME | TABLE_NAME |

+--------------+------------------+------------+

| test         | tg1              | emp_bonus  |

| test         | tg1              | emp_bonus  |

| test         | tg1              | emp        |

| test         | tg1              | emp        |

| test         | tg1              | emp_info   |

| test         | tg1              | emp_info   |

可以看出,product表同emp表不在同一表组,它们的分区方式并不一致。

3 运行两表关联的sql,看一下执行计划

MySQL [test]> explain select a.id,a.name, b.name as prod_name from emp a, product b where a.id=b.producer;

    LOGICAL EXECUTIONPLAN          

    Project(id="id", name="name", prod_name="name0")            

      BKAJoin(condition="producer = id", type="inner")

        Gather(concurrent=true)                                  

          LogicalView(tables="emp[p1,p2]", shardCount=2, sql="SELECT `id`, `name`   FROM `emp` AS `emp`")

        Gather(concurrent=true)                                  

          LogicalView(tables="product[p1,p2,p3]", shardCount=3,  

           sql="SELECT `name`, `producer` FROM `product` AS `product` WHERE (`producer` IN (...))")

    因为分区方式不一致,两个表不属于同一个表组,join操作不能下推到存储节点执行。

4 创建一个全局二级索引

1) 在product表的producer列上创建一个全局二级索引

ALTER TABLE product ADD  GLOBAL INDEX `g_i_emp_id_name` (`producer`) covering('name')  partition by key(`producer`) partitions 2;

2) 查看tg1(emp所在tablegroup)内的表及索引

MySQL [test]> select TABLE_SCHEMA,TABLE_GROUP_NAME,TABLE_NAME from information_schema.TABLE_DETAIL where table_group_name like 'tg1';

+--------------+------------------+-----------------------+

| TABLE_SCHEMA | TABLE_GROUP_NAME | TABLE_NAME            |

+--------------+------------------+-----------------------+

| test         | tg1              | g_i_emp_id_$5917      |

| test         | tg1              | emp_bonus             |

| test         | tg1              | emp                   |

新建索引和emp属于同一tablegroup

3) 查看一下执行计划

MySQL [test]> explain select a.id,a.name, b.name as prod_name from emp a, product b where a.id=b.producer;

    LOGICAL EXECUTIONPLAN          

    Project(id="id", name="name", prod_name="name0")            

      BKAJoin(condition="producer = id", type="inner")

        Gather(concurrent=true)                                  

          LogicalView(tables="emp[p1,p2]", shardCount=2, sql="SELECT `id`, `name`   FROM `emp` AS `emp`")

        Gather(concurrent=true)                                  

          LogicalView(tables="product[p1,p2,p3]", shardCount=3,  

           sql="SELECT `name`, `producer` FROM `product` AS `product` WHERE (`producer` IN (...))")

因为需要回表,join操作仍然不能下推到存储节点执行。

5 创建一个全局覆盖二级索引

1) 在product表producer列上创建一个覆盖索引,覆盖name列

ALTER TABLE product ADD  GLOBAL INDEX `g_i_emp_id_name` (`producer`) covering('name')  partition by key(`producer`) partitions 2;

2) 检查新建索引所属tablegroup

MySQL [test]> select TABLE_SCHEMA,TABLE_GROUP_NAME,TABLE_NAME from information_schema.TABLE_DETAIL where table_group_name like 'tg1';

+--------------+------------------+-----------------------+

| TABLE_SCHEMA | TABLE_GROUP_NAME | TABLE_NAME            |

+--------------+------------------+-----------------------+

| test         | tg1              | g_i_emp_id_$5917      |

| test         | tg1              | emp_bonus             |

| test         | tg1              | emp                   |

| test         | tg1              | g_i_emp_id_name_$5745 |

新建的索引同emp属于一个tablegroup

3) 看一下执行计划

MySQL [test]> explain select a.id,a.name, b.name as prod_name from emp a, product b where a.id=b.producer;  

LOGICAL EXECUTIONPLAN

Gather(concurrent=true)  

  IndexScan(tables="emp[p1,p2],g_i_emp_id_name_$5745[p1,p2]",  shardCount=2, sql="SELECT `emp`.`id`, `emp`.`name`,

      `g_i_emp_id_name_$5745`.`name` AS `prod_name` FROM `emp` AS `emp` INNER JOIN

       `g_i_emp_id_name_$5745` AS `g_i_emp_id_name_$5745` ON (`emp`.`id` = `g_i_emp_id_name_$5745`.`producer`)")

HitCache:false  

Source:PLAN_CACHE

TemplateId: 447db302 

整个join操作被下推到存储节点,使用了g_i_emp_id_name做了索引扫描。

6 结论

从这个小实验可以看出,PolarDB-X可以使用全局覆盖索引将连接操作下推到存储节点执行。





相关实践学习
跟我学:如何一键安装部署 PolarDB-X
《PolarDB-X 动手实践》系列第一期,体验如何一键安装部署 PolarDB-X。
相关文章
|
6天前
|
关系型数据库 分布式数据库 数据库
PolarDB常见问题之加了索引但是查询没有使用如何解决
PolarDB是阿里云推出的下一代关系型数据库,具有高性能、高可用性和弹性伸缩能力,适用于大规模数据处理场景。本汇总囊括了PolarDB使用中用户可能遭遇的一系列常见问题及解答,旨在为数据库管理员和开发者提供全面的问题指导,确保数据库平稳运行和优化使用体验。
|
6天前
|
存储 关系型数据库 分布式数据库
数据库索引回表困难?揭秘PolarDB存储引擎优化技术
PolarDB分布式版存储引擎采用CSM方案均衡资源开销与可用性。
数据库索引回表困难?揭秘PolarDB存储引擎优化技术
|
6天前
|
SQL 关系型数据库 分布式数据库
数据库索引,一文揭秘PolarDB XPlan索引选择
深度解读PolarDB分布式版XPlan的索引选择
数据库索引,一文揭秘PolarDB XPlan索引选择
|
6天前
|
SQL 算法 关系型数据库
PolarDB-X的XPlan索引选择
对于数据库来说,正确的选择索引是基本的要求,选错索引轻则导致查询缓慢,重则导致数据库整体不可用。PolarDB-X存在多种不同的索引,局部索引、全局索引、列存索引、归档表索引。本文主要介绍一种CN上的局部索引算法:XPlan索引选择。
125780 13
PolarDB-X的XPlan索引选择
|
6天前
|
关系型数据库 定位技术 索引
在关系型数据库中,常见的索引种类包括哪些
在关系型数据库中,常见的索引种类包括哪些
494 0
|
6天前
|
存储 关系型数据库 分布式数据库
PolarDB-X HTAP新特性 ~ 列存索引
随着数据爆炸式的增长,传统的OLTP和OLAP解决方案基于简单的读写分离或ETL模型,将在线库的数据以T+1的方式抽取到数据仓库中进行计算,这种方案存在存储成本高、实时性差、链路和维护成本高等缺陷。 为应对数据爆炸式增长的挑战,PolarDB分布式版本基于对象存储设计了一套列存索引(Clustered Columnar Index,CCI)功能,支持将行存数据实时同步到列存存储上
76014 148
|
7月前
|
关系型数据库 MySQL 分布式数据库
PolarDB MySQL版重磅推出的列存索引(
PolarDB MySQL版重磅推出的列存索引(
345 1
|
7月前
|
关系型数据库 Go 数据库
《提高查询速度:PostgreSQL索引实用指南》
《提高查询速度:PostgreSQL索引实用指南》
396 0
|
7月前
|
SQL 缓存 关系型数据库
PolarDB-X 混沌测试实践:如何衡量数据库索引选择能力
随着PolarDB分布式版的不断演进,功能不断完善,新的特性不断增多,整体架构扩大的同时带来了测试链路长,出现问题前难发现,出现问题后难排查等等问题。原有的测试框架已经难以支撑实际场景的复杂模拟测试。因此,我们实现了一个基于业务场景面向优化器索引选择的混沌查询实验室,本文之后简称为CEST(complex environment simulation test)。
|
8月前
|
关系型数据库 分布式数据库 数据库
PolarDB for PostgreSQL 14:全局索引
PolarDB for PostgreSQL 14 相较于 PostgreSQL 14,提供了更多企业级数据库的特性。本实验将体验其中的全局索引功能。
770 0