如何在PostgreSQL中使用partial index来优化SQL?
Posted 黄伟DBCA
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在PostgreSQL中使用partial index来优化SQL?相关的知识,希望对你有一定的参考价值。
一 案例背景
从生产控制台上看到一条下述SQL:
格式化之后SQL语句为:
select '01' status, count(1) from t_ai_prd_item where status = '01' and deleted = false
union all
select '02' status, count(1) from t_ai_prd_item where status = '02' and deleted = false
一个union all的联合查询,每次执行耗时1秒。有没有优化余地呢?
二 优化分析
1 查看原表数据量分布:
ai=> select count(*) from t_ai_prd_item;
count
---------
1395189
(1 row)
ai=> select count(*),status from t_ai_prd_item group by status;
count | status
---------+--------
364 | 04
25 | 05
2835 | 02
1391965 | 06
(4 rows)
ai=>
分析发现,表1中有1395189条记录,status='01'的记录为0,status='02'的记录为2835条。
2 那么在status字段上建立一个btree index,效果会怎么样呢?
效果不错,但是结合到实际业务场景,此处只是针对status='01'和status='02'的情况来做统计。那么有没有更好的方法来解决这个场景呢?
3 创建1个partial index来测试
对比,发现SQL的执行效率几乎没有差别。但是:
4 小结:
在确保SQL执行效率的同时,这个partial index所占的存储空间是b-tree index的1/384,大大降低了存储空间的开销。
三 关于partial index
1 什么是partial index?
分区索引是基于表中部分数据建立的,被索引的部分数据是原数据的一个子集。这个子集数据是基于某些条件可以明确计算出来的。
2 partial index适用场景?
对于表中数据分布“不均匀”的场景,比如某些数据占据绝大多数,而其它一些数据只占少量,且要满足查询条件针是对那些小数据量的查询情形。此例正好满足这种情况,总数据量为140万左右,而状态为01和02的数据只占极少的比例,且查询是针对状态为01和02的查询。
通过partial index可以排除大量普通数据或业务上“不感兴趣”的数据。如:一个在线订单系统,可以针对那些不在经常访问的客户端IP范围之外的IP进行创建分区索引,或者针对已下单还未支付的订单进行分区索引的创建。这样,当查询那些不在常用IP范围内的订单,或者那些已下单未支付的订单信息时,可以保证查询效率。
3 partial index的优势?
由于其是针对部分数据进行索引,显然同传统b-tree索引相比,其所占磁盘空间将大大缩小。当重建维护这些分区索引时,速度也非常快。
4 参考
https://www.postgresql.org/docs/9.3/static/indexes-partial.html
以上是关于如何在PostgreSQL中使用partial index来优化SQL?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 prisma / postgresql 中拥有自定义 ID?
如何在 TypeScript 中定义一个 Partials 数组?