开启和使用向量化引擎

本文介绍如何开启向量化引擎,以及开启功能后的使用方式。

前提条件

  • 支持的PolarDB PostgreSQL的版本如下:

    PostgreSQL 14(内核小版本2.0.14.10.20.0及以上)

    说明

    您可通过如下语句查看PolarDB PostgreSQL的内核小版本号:

    SHOW polardb_version;

    如不满足内核小版本要求,请升级内核小版本

  • 原表必须包含主键,且在创建列存索引时需要将主键列加入列存索引中。

  • wal_level参数的值需设置为logical,即在预写式日志WAL(Write-ahead logging)中增加支持逻辑编码所需的信息。

    说明

    您可以通过控制台设置wal_level参数。修改该参数后集群将会重启,请在修改参数前做好业务安排,谨慎操作。

使用限制

  • 一张表只能创建一个列存索引。

  • 不支持修改列存索引。如需在列存索引添加列,请重建列存索引。

安装向量化引擎插件

PolarDB PostgreSQL向量化引擎作为插件(polar_csi)部署在数据库集群中,在使用之前需要在指定的数据库中创建插件。

说明

polar_csi插件的作用域是Database级别,如果需要在集群的多个Database中使用向量化引擎能力,需要为每个Database分别创建polar_csi插件。

您可以选择以下两种方式中的任意一种安装polar_csi插件。

控制台安装

  1. 登录PolarDB控制台,选择集群所在地域,在集群列表中单击目标集群ID进入详情页。

  2. 在左侧导航栏选择配置与管理 > 插件管理,在管理插件页签,选中未安装插件

  3. 在页面右上角选择目标数据库,单击polar_csi插件操作列安装,在弹出的安装插件对话框,选择目标数据库账号,单击确定,即将插件安装到目标数据库中。

    image.png

    说明

    安装插件使用的数据库账号必须为高权限账号

命令行安装

连接数据库集群,并在具有相应权限的目标数据库中执行以下语句,创建polar_csi插件。

CREATE EXTENSION polar_csi;

使用说明

管理列存索引

使用向量化引擎之前,需要对表创建列存索引。

说明

当为数据量较大的表创建列存索引时,该过程可能耗费较长时间。优化列存索引创建速度请参见提升索引创建速度

创建列存索引

语法
-- 为部分列创建索引
CREATE INDEX [ CONCURRENTLY ] csi_index_name ON table_name USING CSI(column1,column2,...);
-- 为所有列创建索引
CREATE INDEX [ CONCURRENTLY ] csi_index_name ON table_name USING CSI;
参数说明

参数

描述

CONCURRENTLY

可选,使用并发模式创建索引。不会阻塞原表的写入操作,适用于对线上已有表的索引创建。

说明
  • PostgreSQL 14且内核小版本2.0.14.13.27.0及以上集群支持使用该参数。如不满足内核小版本要求,请升级内核小版本

  • CONCURRENTLY的实现依赖逻辑复制槽功能,在内核小版本2.0.14.13.27.0及以上集群上创建插件时,该功能将默认激活。如使用旧版本,建议重装polar_csi插件或联系我们处理。

  • 使用CONCURRENTLY创建索引时,会创建临时逻辑复制槽以支持并发操作。数据同步完成后,临时逻辑复制槽将自动释放。

csi_index_name

自定义的列存索引名称。

table_name

需要创建列存索引的表名称。

column1,column2,...

指定创建列存索引的表的具体列,如不指定则为所有列创建索引。

示例
  1. 准备基础测试表sales

    CREATE TABLE sales (sale_id int primary key, name CHAR(10), amount int);
  2. 创建列存索引。由于一张表只能创建一个列存索引,请选择执行以下任一语句以为指定表创建列存索引。

    指定列创建列存索引

    CREATE INDEX idx_csi_sales ON sales USING CSI(sale_id, amount);

    所有列创建列存索引

    CREATE INDEX idx_csi_sales ON sales USING CSI;

    使用并发模式为指定列创建列存索引

    并发模式下创建列存索引不会阻塞原表的写入操作,适用于对线上已有表进行索引创建。

    CREATE INDEX CONCURRENTLY idx_csi_sales ON sales USING CSI(sale_id, amount);

    创建索引成功后可使用以下语句查看索引情况:

    SELECT * FROM pg_indexes WHERE tablename = 'sales';

重建列存索引

语法
REINDEX INDEX csi_index_name;
参数说明

参数

描述

csi_index_name

需要重建的列存索引名称。

示例

重建之前创建的列存索引。

REINDEX INDEX idx_csi_sales; 

查看索引创建进度

当为数据量较大的表创建列存索引时,该过程可能耗费较长时间。可通过以下方式查看索引创建的进度:

SELECT * FROM pg_stat_progress_create_index;

查看索引大小

可以使用pg_relation_size函数查看索引大小,并结合pg_size_pretty函数以更友好的方式进行显示。

SELECT * FROM pg_size_pretty(pg_relation_size('csi_index_name'));
示例

查看之前创建的列存索引占用的存储空间大小。

SELECT * FROM pg_size_pretty(pg_relation_size('idx_csi_sales'));

取消索引创建

在为数据量较大的表创建列存索引时,该过程可能会耗费较长时间。如果创建索引进程对现有业务产生影响,可通过pg_cancel_backendpg_terminate_backend取消索引的创建。

SELECT pg_cancel_backend(pid);

SELECT pg_terminate_backend(pid);

其中,pid可通过查看索引创建进度获取。

删除列存索引

语法
DROP INDEX csi_index_name;
参数说明

参数

描述

csi_index_name

需要删除的列存索引名称。

示例

删除之前创建的列存索引。

DROP INDEX idx_csi_sales;

列存索引的实时性

PolarDB PostgreSQL向量化引擎不仅支持对历史数据创建列存索引,还能够自动将行存表中的新数据同步至列存索引。当使用CREATE INDEX语句为表创建列存索引后,之后新增的数据将实时写入列存索引,且无需对该过程进行额外操作。可通过调整参数提升列存索引的实时性

使用向量化引擎功能

参数设置

安装插件后,默认未启用向量化引擎功能,需要设置以下参数开启。

  • polar_csi.enable_query:是否允许查询语句使用向量化引擎,取值如下:

    • off(默认):不允许查询语句使用向量化引擎。

    • on:允许查询语句使用向量化引擎。

      SET polar_csi.enable_query = on;
  • polar_csi.cost_threshold:查询代价阈值,是否使用向量化引擎。如果查询代价小于当前设置阈值,使用行存引擎,反之使用向量化引擎。

    SET polar_csi.cost_threshold = 0;
    说明

    将值设置为0时,所有查询语句都将优先采用向量化引擎。不建议在实际业务中将值设置为0,请根据行存引擎与向量化引擎的负载情况动态调整该值。

参数生效范围

  • 全局范围

    当前数据库内所有查询语句都会尝试使用向量化引擎。需要设置polar_csi.enable_query参数的值为on。您可以通过控制台设置wal_level参数

  • 会话级

    会话内的所有查询都会尝试使用向量化引擎。

    SET polar_csi.enable_query = ON;
  • SQL语句级

    会话内的单个SQL查询语句使用向量化引擎,可通过Hint方式实现。

    说明

    依赖pg_hint_plan插件的能力,需要在目标数据库执行CREATE EXTENSION pg_hint_plan;以安装该插件。

    /*+ SET (polar_csi.enable_query on/off) */ SELECT COUNT(*) FROM sales;

查看SQL是否使用列存索引

通过ExplainExplain Analyze等工具打印查询计划,出现CSI Executor关键词时即表示该查询已经使用列存索引。

EXPLAIN SELECT COUNT(*) FROM sales;

返回结果如下:

  QUERY PLAN  
--------------
 CSI Executor
(1 row)

查询一致性

PolarDB PostgreSQL向量化引擎支持两种查询一致性级别,以满足不同业务需求。

  • 最终一致性(默认):适用于写入负载高,但对数据实时性要求低的查询。

  • 强一致性:在列存数据与行存数据完全一致后再返回查询结果。

PolarDB PostgreSQL目前PolarDB PostgreSQL 向量化引擎的列存索引实时性可以在秒级,但当写入负载过大时,列存索引的数据延迟会升高。默认的一致性级别为最终一致性,所以当写入负载过大,且 SQL 查询使用列存索引时,可能无法查出最新的数据。

为了满足某些业务场景下的行列强一致性,PolarDB PostgreSQL向量化引擎支持强一致性读功能,当查询时,向量化引擎会等待列存索引的数据与行存数据一致时才会执行。

性能调优

提升索引创建速度

索引创建速度与多个参数有关,如下所示:

参数名

取值范围

默认值

描述

polar_csi.memory_limit

1~1048576

1024

向量化引擎可以使用的内存大小,单位:MB。

内存阈值越大,索引创建越快。请根据集群规格来调整该参数的值,建议不超过集群内存的20%,否则可能造成OOM的风险。

polar_csi.flush_count

2048~20480000

204800

批次提交的行数。

增加行数能够提高创建效率,但同时也需要占用更多内存。

提升列存索引的实时性

PolarDB PostgreSQLPostgreSQL 14在内核小版本2.0.14.13.28.0及以上版本(仅针对PostgreSQL 14数据库引擎版本)增加如下参数,可通过调整参数提升行列转换速度,从而提升列存索引的实时性

参数名

取值范围

默认值

作用

polar_csi.update_interval

0~3600

3

定期更新时间间隔,单位:秒。

增大更新间隔可以合并同类型的小事务,从而在事务数量较多时提高数据更新效率。

polar_csi.update_batch_count

1024~4294967295

100000

批量更新行数的阈值。

一个更新事务的最大行数,增加该阈值可以提升数据更新的效率。

提升查询速度

查询性能主要与以下参数有关,可通过调整参数值提升查询性能:

参数名

取值范围

默认值

作用

polar_csi.exec_parallel

1~512

2

向量化引擎执行单条查询语句的并行度。

一般来说并行度越大性能越好。与集群资源规格相关,请根据集群规格来调整该参数的值,建议不超过计算节点的CPU核数。

polar_csi.memory_limit

1~1048576

1024

向量化引擎可以使用的内存,单位:MB。

请根据集群规格来调整该参数的值,建议不超过集群内存的20%,否则可能造成OOM的风险。

polar_csi.cost_threshold

1~1000000000

50000

查询代价阈值,是否使用向量化引擎。如果查询代价小于当前设置阈值,使用行存引擎,反之使用向量化引擎。

当该参数的取值过大时,会导致耗时的SQL语句无法使用向量化引擎,查询较慢。当该参数的取值过小时,会导致简单SQL使用向量化引擎,降低系统的并发度。请根据实际业务负载进行调整。

说明

PolarDB PostgreSQLPostgreSQL 14在内核小版本14.13.28.0及以上版本(仅针对PostgreSQL 14数据库引擎版本)调整参数默认值为50000,在此之前默认值为1000。

polar_csi.forward_replay_wait

on|off

off

查询一致性级别,取值如下:

  • off:表示最终一致性,列存索引的数据可能会落后于行存。

  • on:表示强一致性,查询过程中会等待列存数据回放到最新数据时才会执行。当写入压力较大时,开启该参数,可能会造成等待时间过长。

完整示例

  1. 安装polar_csi插件。

    CREATE EXTENSION polar_csi;
  2. 创建测试表。

    CREATE TABLE sales (sale_id int primary key, name CHAR(10), amount int);
  3. 为测试表创建列存索引。

    CREATE INDEX idx_csi_sales ON sales USING CSI(sale_id, name, amount);
  4. 为测试表插入测试数据。

    INSERT INTO sales values(1, 'hat', 10);
    INSERT INTO sales values(2,'glove',6);
    INSERT INTO sales values(3,'t-shirt',220);
  5. 使用向量化引擎,统计销量最高的物品。

    • 启用向量化引擎功能

      -- 开启polar_csi.enable_query参数
      SET polar_csi.enable_query to on;
      
      -- 由于示例表中数据较小,此处将polar_csi.cost_threshold设置为0,所有查询都会被转发到向量化引擎
      SET polar_csi.cost_threshold to 0;
    • 查看SQL执行计划。

      EXPLAIN SELECT sale_id, name, amount
      FROM sales
      WHERE amount = (
          SELECT MAX(amount)
          FROM sales
      );

      返回结果包括CSI Executor,即使用向量化引擎。

        QUERY PLAN  
      --------------
       CSI Executor
      (1 row)