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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云原生数据库 PolarDB 分布式版,标准版 2核8GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介: 使用全局索引将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开源数据库
本实验环境已内置PostgreSQL数据库以及PolarDB开源数据库:PolarDB PostgreSQL版和PolarDB分布式版,支持一键拉起使用,方便各位开发者学习使用。
相关文章
|
5月前
|
存储 缓存 负载均衡
【PolarDB-X 技术揭秘】Lizard B+tree:揭秘分布式数据库索引优化的终极奥秘!
【8月更文挑战第25天】PolarDB-X是阿里云的一款分布式数据库产品,其核心组件Lizard B+tree针对分布式环境优化,解决了传统B+tree面临的数据分片与跨节点查询等问题。Lizard B+tree通过一致性哈希实现数据分片,确保分布式一致性;智能分区实现了负载均衡;高效的搜索算法与缓存机制降低了查询延迟;副本机制确保了系统的高可用性。此外,PolarDB-X通过自适应分支因子、缓存优化、异步写入、数据压缩和智能分片等策略进一步提升了Lizard B+tree的性能,使其能够在分布式环境下提供高性能的索引服务。这些优化不仅提高了查询速度,还确保了系统的稳定性和可靠性。
107 5
|
5月前
|
存储 算法 Cloud Native
【PolarDB-X列存魔法】揭秘TPC-H测试背后的性能优化秘籍!
【8月更文挑战第25天】阿里巴巴的云原生数据库PolarDB-X以其出色的性能、可靠性和扩展性闻名,在多种业务场景中广泛应用。尤其在列存储模式下,PolarDB-X针对分析型查询进行了优化,显著提升了数据读取效率。本文通过TPC-H基准测试探讨PolarDB-X列存执行计划的优化策略,包括高效数据扫描、专用查询算法以及动态调整执行计划等功能,以满足复杂查询的需求并提高数据分析性能。
126 1
|
6月前
|
SQL 关系型数据库 分布式数据库
PolarDB产品使用问题之相同的SQL语句在不同时间执行EXPLAIN计划显示出不同的索引类型,是什么原因
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
PolarDB产品使用问题之相同的SQL语句在不同时间执行EXPLAIN计划显示出不同的索引类型,是什么原因
|
5月前
|
C# UED 定位技术
WPF控件大全:初学者必读,掌握控件使用技巧,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,控件是实现用户界面交互的关键元素。WPF提供了丰富的控件库,包括基础控件(如`Button`、`TextBox`)、布局控件(如`StackPanel`、`Grid`)、数据绑定控件(如`ListBox`、`DataGrid`)等。本文将介绍这些控件的基本分类及使用技巧,并通过示例代码展示如何在项目中应用。合理选择控件并利用布局控件和数据绑定功能,可以提升用户体验和程序性能。
103 0
|
6月前
|
SQL 关系型数据库 分布式数据库
PolarDB产品使用问题之如何实现在线上加索引,并且不会锁表
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
6月前
|
关系型数据库 分布式数据库 数据库
PolarDB产品使用问题之Join评估的行数比索引的基数小,是什么导致的
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
7月前
|
关系型数据库 MySQL 分布式数据库
PolarDB产品使用问题之mysql迁移后查询不走索引了,该如何解决
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
7月前
|
运维 关系型数据库 分布式数据库
PolarDB产品使用问题之列存索引的原理是什么
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
7月前
|
存储 算法 数据处理
惊人!PolarDB-X 存储引擎核心技术的索引回表优化如此神奇!
【6月更文挑战第11天】PolarDB-X存储引擎以其索引回表优化技术引领数据库发展,提升数据检索速度,优化磁盘I/O,确保系统在高并发场景下的稳定与快速响应。通过示例代码展示了在查询操作中如何利用该技术高效获取结果。索引回表优化具备出色性能、高度可扩展性和适应性,为应对大数据量和复杂业务提供保障,助力企业与开发者实现更高效的数据处理。
75 3
|
8月前
|
关系型数据库 数据库 索引
关系型数据库选择正确的索引类型
【5月更文挑战第20天】
156 5