“当复杂的SQL不在需要特别的优化”,邪修研究PolarDB for PG 列式索引加速复杂SQL运行
❝开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, OceanBase, Sql Server等有问题,有需求都可以加群群内有各大数据库行业大咖,可以解决你的问题。加群请联系 liuaustin3 ,(共3300人左右 1 + 2 + 3 + 4 +5 + 6 + 7 + 8 +9)(1 2 3 4 5 6 7群均已爆满,开8群近400 9群 200+,开10群PolarDB专业学习群100+)
PolarDB for PostgreSQL 中包含了了一个Polar_csi的插件,通过在PolarDB for PostgreSQL 上安装插件的方式来使用向量引擎,列式索引。
这里需要提醒使用列式索引的前提条件
1 wal_level 参数必须设置为logical
2 一张表只能有一个列式索引
3 列式索引建立后不能修改,只能重建
4 安装polar_csi插件后,需要在数据库中执行create extension polar_csi 命令
5 是否启用polar_csi 有开关命令可以进行验证
同时要修改参数
test=> create extension polar_csi;
CREATE EXTENSION
test=>
test=> -- 创建 customers 表
test=> CREATE TABLE customers (
test(> customer_id SERIAL PRIMARY KEY,
test(> name VARCHAR(100),
test(> email VARCHAR(100),
test(> created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
test(> );
CREATE TABLE
test=>
test=> -- 创建 products 表
test=> CREATE TABLE products (
test(> product_id SERIAL PRIMARY KEY,
test(> name VARCHAR(100),
test(> price DECIMAL(10, 2),
test(> created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
test(> );
CREATE TABLE
test=>
test=> -- 创建 orders 表
test=> CREATE TABLE orders (
test(> order_id SERIAL PRIMARY KEY,
test(> customer_id INT REFERENCES customers(customer_id),
test(> product_id INT REFERENCES products(product_id),
test(> order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
test(> quantity INT,
test(> total_amount DECIMAL(10, 2)
test(> );
针对这三张表我们每张表插入100,200万数据。
test=> \d
List of relations
Schema | Name | Type | Owner
--------+---------------------------+----------+----------
public | customers | table | dba_test
public | customers_customer_id_seq | sequence | dba_test
public | orders | table | dba_test
public | orders_order_id_seq | sequence | dba_test
public | products | table | dba_test
public | products_product_id_seq | sequence | dba_test
(6 rows)
test=> select count(*) from customers;
count
---------
2000000
(1 row)
test=> explain analyze select count(*) from customers;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (cost=27472.22..27472.23 rows=1 width=8) (actual time=139.527..142.490 rows=1 loops=1)
-> Gather (cost=27472.00..27472.21 rows=2 width=8) (actual time=136.042..142.482 rows=3 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Partial Aggregate (cost=26472.00..26472.01 rows=1 width=8) (actual time=125.038..125.038 rows=1 loops=3)
-> Parallel Index Only Scan using customers_pkey on customers (cost=0.43..24388.62 rows=833354 width=0) (actual time=0.202..90.587 rows=666667 loops=3)
Heap Fetches: 0
Planning Time: 0.040 ms
Execution Time: 142.566 ms
(9 rows)
test=> select count(*) from orders;
count
---------
1000000
(1 row)
test=> select count(*) from products;
count
---------
2000000
(1 row)
test=>
同时在数据库查询中,无法优化的SQL聚合加子查询,且没有数据的过滤,即使建立了索引也无法使用还是要走全表扫描等。
test=> explain analyze SELECT
test-> c.customer_id,
test-> c.name,
test-> COALESCE(order_counts.total_orders, 0) AS total_orders,
test-> COALESCE(order_totals.total_spent, 0) AS total_spent
test-> FROM
test-> customers c
test-> LEFT JOIN (
test(> SELECT
test(> customer_id,
test(> COUNT(order_id) AS total_orders
test(> FROM
test(> orders
test(> GROUP BY
test(> customer_id
test(> ) AS order_counts ON c.customer_id = order_counts.customer_id
test-> LEFT JOIN (
test(> SELECT
test(> customer_id,
test(> SUM(total_amount) AS total_spent
test(> FROM
test(> orders
test(> GROUP BY
test(> customer_id
test(> ) AS order_totals ON c.customer_id = order_totals.customer_id
test-> ORDER BY
test-> total_spent DESC;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------
Gather Merge (cost=217678.61..412136.56 rows=1666666 width=77) (actual time=1407.023..2104.550 rows=2000000 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Sort (cost=216678.59..218761.92 rows=833333 width=77) (actual time=1323.073..1454.480 rows=666667 loops=3)
Sort Key: (COALESCE(order_totals.total_spent, '0'::numeric)) DESC
Sort Method: external merge Disk: 46088kB
Worker 0: Sort Method: external merge Disk: 52096kB
Worker 1: Sort Method: external merge Disk: 21328kB
-> Hash Left Join (cost=47408.07..91348.40 rows=833333 width=77) (actual time=633.505..938.891 rows=666667 loops=3)
Hash Cond: (c.customer_id = order_totals.customer_id)
-> Hash Left Join (cost=23704.03..65456.86 rows=833333 width=45) (actual time=292.432..479.223 rows=666667 loops=3)
Hash Cond: (c.customer_id = order_counts.customer_id)
-> Parallel Seq Scan on customers c (cost=0.00..39565.33 rows=833333 width=37) (actual time=0.003..65.482 rows=666667 loops=3)
-> Hash (cost=23704.02..23704.02 rows=1 width=12) (actual time=292.407..292.409 rows=1 loops=3)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
-> Subquery Scan on order_counts (cost=23704.00..23704.02 rows=1 width=12) (actual time=292.398..292.400 rows=1 loops=3)
-> HashAggregate (cost=23704.00..23704.01 rows=1 width=12) (actual time=292.397..292.398 rows=1 loops=3)
Group Key: orders.customer_id
Batches: 1 Memory Usage: 25kB
Worker 0: Batches: 1 Memory Usage: 25kB
Worker 1: Batches: 1 Memory Usage: 25kB
-> Seq Scan on orders (cost=0.00..18704.00 rows=1000000 width=8) (actual time=0.003..86.712 rows=1000000 loops=3)
-> Hash (cost=23704.02..23704.02 rows=1 width=36) (actual time=341.045..341.049 rows=1 loops=3)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
-> Subquery Scan on order_totals (cost=23704.00..23704.02 rows=1 width=36) (actual time=341.034..341.036 rows=1 loops=3)
-> HashAggregate (cost=23704.00..23704.01 rows=1 width=36) (actual time=341.032..341.034 rows=1 loops=3)
Group Key: orders_1.customer_id
Batches: 1 Memory Usage: 25kB
Worker 0: Batches: 1 Memory Usage: 25kB
Worker 1: Batches: 1 Memory Usage: 25kB
-> Seq Scan on orders orders_1 (cost=0.00..18704.00 rows=1000000 width=11) (actual time=0.003..75.037 rows=1000000 loops=3)
Planning Time: 1.507 ms
Execution Time: 2186.800 ms
(33 rows)
在没有动过任何的语句和添加更多索引的情况下,我们打开列式查询,再次验证查询的情况。
test=> SET polar_csi.enable_query = on;
SET
Time: 7.092 ms
test=> explain analyze SELECT
test-> c.customer_id,
test-> c.name,
test-> COALESCE(order_counts.total_orders, 0) AS total_orders,
test-> COALESCE(order_totals.total_spent, 0) AS total_spent
test-> FROM
test-> customers c
test-> LEFT JOIN (
test(> SELECT
test(> customer_id,
test(> COUNT(order_id) AS total_orders
test(> FROM
test(> orders
test(> GROUP BY
test(> customer_id
test(> ) AS order_counts ON c.customer_id = order_counts.customer_id
test-> LEFT JOIN (
test(> SELECT
test(> customer_id,
test(> SUM(total_amount) AS total_spent
test(> FROM
test(> orders
test(> GROUP BY
test(> customer_id
test(> ) AS order_totals ON c.customer_id = order_totals.customer_id
test-> ORDER BY
test-> total_spent DESC;
QUERY PLAN
--------------
CSI Executor
(1 row)
Time: 824.630 ms
test=>
整体语句查询的速度提高了3倍左右。
那么除了通过csi优化的方法,在csi中是否还有方案可以继续优化查询的速度。
1 通过 polar_csi.memory_limit 的方案默认这个memory_limit使用的是1024MB,这是指的向量化引擎可以使用的内存大小,我们将默认的1024改为2048后,我们在次查询,查询速度提高了224ms,占原有速度的25%,提高可4分之一的查询速度。
除此以外我们还可以通过增加并行的方式提高查询的速度。
最后通过普通的查询索引的语句就可以看到csi类的索引以及创建的列数。
写到结尾:作为一个邪修DBA架构,我就是愿意和别人不一样,走那些走烂的路,一条路别人走过,你在走只能叫尾随,如果是你第一个走,你叫开拓者,生存的意义最终都是在争夺第一次,不是吗?
置顶
“合体吧兄弟们!”——从浪浪山小妖怪看OceanBase国产芯片优化《OceanBase “重如尘埃”之歌》
未知黑客通过SQL SERVER 窃取企业SAP核心数据,影响企业运营
那个MySQL大事务比你稳定,主从延迟低,为什么? Look my eyes! 因为宋利兵宋老师
非“厂商广告”的PolarDB课程:用户共创的新式学习范本--7位同学获奖PolarDB学习之星
说我PG Freezing Boom 讲的一般的那个同学,专帖给你,看看这次可满意
这个 PostgreSQL 让我有资本找老板要 鸡腿 鸭腿 !!
OceanBase Hybrid search 能力测试,平换MySQL的好选择
HyBrid Search 实现价值落地,从真实企业的需求角度分析 !不只谈技术!
OceanBase 光速快递 OB Cloud “MySQL” 给我,Thanks a lot
从“小偷”开始,不会从“强盗”结束 -- IvorySQL 2025 PostgreSQL 生态大会
被骂后的文字--技术人不脱离思维困局,终局是个 “死” ? ! ......
个群2025上半年总结,OB、PolarDB, DBdoctor、爱可生、pigsty、osyun、工作岗位等
从MySQL不行了,到乙方DBA 给狗,狗都不干? 我干呀!
SQL SERVER 2025发布了, China幸亏有信创!
MongoDB 麻烦专业点,不懂可以问,别这么用行吗 ! --TTL
PostgreSQL 新版本就一定好--由培训现象让我做的实验
删除数据“八扇屏” 之 锦门英豪 --我去-BigData!
写了3750万字的我,在2000字的OB白皮书上了一课--记 《OceanBase 社区版在泛互场景的应用案例研究》
跟我学OceanBase4.0 --阅读白皮书 (OB分布式优化哪里了提高了速度)
跟我学OceanBase4.0 --阅读白皮书 (4.0优化的核心点是什么)
跟我学OceanBase4.0 --阅读白皮书 (0.5-4.0的架构与之前架构特点)
跟我学OceanBase4.0 --阅读白皮书 (旧的概念害死人呀,更新知识和理念)
MongoDB 相关文章
MongoDB “升级项目” 大型连续剧(4)-- 与开发和架构沟通与扫尾
MongoDB “升级项目” 大型连续剧(3)-- 自动校对代码与注意事项
MongoDB “升级项目” 大型连续剧(2)-- 到底谁是"der"
MongoDB “升级项目” 大型连续剧(1)-- 可“生”可不升
MongoDB 大俗大雅,上来问分片真三俗 -- 4 分什么分
MongoDB 大俗大雅,高端知识讲“庸俗” --3 奇葩数据更新方法
MongoDB 大俗大雅,高端的知识讲“通俗” -- 2 嵌套和引用
MongoDB 大俗大雅,高端的知识讲“低俗” -- 1 什么叫多模
MongoDB 合作考试报销活动 贴附属,MongoDB基础知识速通
MongoDB 使用网上妙招,直接DOWN机---清理表碎片导致的灾祸 (送书活动结束)
MongoDB 2023年度纽约 MongoDB 年度大会话题 -- MongoDB 数据模式与建模
免费PolarDB云原生课程,听课“争”礼品,重塑云上知识,提高专业能力
“PostgreSQL” 高性能主从强一致读写分离,我行,你没戏!
POLARDB 添加字段 “卡” 住---这锅Polar不背
PolarDB 版本差异分析--外人不知道的秘密(谁是绵羊,谁是怪兽)
PolarDB 答题拿-- 飞刀总的书、同款卫衣、T恤,来自杭州的Package(活动结束了)
PolarDB for MySQL 三大核心之一POLARFS 今天扒开它--- 嘛是火
PostgreSQL 无服务 Neon and Aurora 新技术下的新经济模式 (翻译)
“PostgreSQL” 高性能主从强一致读写分离,我行,你没戏!
全世界都在“搞” PostgreSQL ,从Oracle 得到一个“馊主意”开始
PostgreSQL 加索引系统OOM 怨我了--- 不怨你怨谁
PostgreSQL “我怎么就连个数据库都不会建?” --- 你还真不会!
PostgreSQL 稳定性平台 PG中文社区大会--杭州来去匆匆
PostgreSQL 分组查询可以不进行全表扫描吗?速度提高上千倍?
POSTGRESQL --Austindatabaes 历年文章整理
PostgreSQL 查询语句开发写不好是必然,不是PG的锅
MySQL相关文章