如何在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,效果会怎么样呢?

如何在PostgreSQL中使用partial index来优化SQL?

效果不错,但是结合到实际业务场景,此处只是针对status='01'和status='02'的情况来做统计。那么有没有更好的方法来解决这个场景呢?


3 创建1个partial index来测试 

如何在PostgreSQL中使用partial index来优化SQL?

对比,发现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 数组?

mysql PDO如何绑定LIKE

如何在另一个控制器的上下文中使用rails form partial而不将ID作为隐藏字段传递

HDOJ5534Partial Tree(树,背包DP)

如何在postgresql中匹配列数,如果大于2,则更新表。