第18节-索引-Partial-Indexes

摘要 :在本教程中,您将学习如何使用 PostgreSQL 分部索引仅对满足指定条件的数据进行索引。

PostgreSQL 分部索引简介

当您创建包含一列或一组列的索引时,PostgreSQL 会从这些列中提取所有数据以进行索引。

PostgreSQL 允许您在表中仅包含满足索引中指定条件的数据子集。该索引称为 partial index

要创建部分索引,请将以下 CREATE INDEX 语句与 WHERE 子句一起使用:

sql 复制代码
CREATE INDEX [index_name]
ON table_name (column1, column2)
WHERE condition;

在此语法中:

  • 首先,在 CREATE INDEX 关键字后指定索引名称。索引名称是可选的。
  • 其次,提供表名后跟要包含在索引中的一列或多列。
  • 第三,在 WHERE 子句中定义一个条件,以指定索引中应包含哪些行。仅包含满足条件的行。

当您从表中查询数据时,PostgreSQL 将仅对索引中包含的行使用部分索引。

PostgreSQL 分部索引示例

首先,创建一个 products 表:

sql 复制代码
CREATE TABLE products (
  id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  price DEC(10, 2) NOT NULL,
  discontinued BOOL
);

接下来,创建一个函数以将行插入到 products 表中:

sql 复制代码
CREATE OR REPLACE FUNCTION insert_products (n INT) 
RETURNS VOID 
AS 
$$
DECLARE
   i INT;
BEGIN
   FOR i IN 1..n LOOP
      INSERT INTO products (name, price, discontinued)
      VALUES (
       'Product_' || i, -- Generating a simple name
       ROUND((RANDOM() * 100 + 1)::numeric, 2), -- Corrected casting for rounding
       CASE WHEN RANDOM() < 0.2 THEN TRUE ELSE FALSE END -- 20% chance of being discontinued
      );
   END LOOP;
END;
$$ 
LANGUAGE plpgsql;

然后,调用 insert_products 函数在 products 表中插入 1000 行:

sql 复制代码
SELECT insert_products(1000);

之后,创建一个仅包含活跃产品的索引:

sql 复制代码
CREATE INDEX ON products (price)
WHERE
  discontinued = FALSE;

此查询创建一个部分索引 products_price_idx ,其中仅包含已停产 false 的产品。

最后,检索活动产品:

sql 复制代码
EXPLAIN SELECT
  name,
  price
FROM
  products
WHERE
  discontinued = FALSE
  AND price < 100;

输出:

sql 复制代码
                                    QUERY PLAN
-----------------------------------------------------------------------------------
 Bitmap Heap Scan on products  (cost=9.57..18.66 rows=167 width=532)
   Recheck Cond: ((price < '100'::numeric) AND (NOT discontinued))
   ->  Bitmap Index Scan on products_price_idx  (cost=0.00..9.53 rows=167 width=0)
         Index Cond: (price < '100'::numeric)

输出指示查询使用 products_price_idx 索引。

如果您查询已停产的产品,PostgreSQL 将不会使用该索引。例如:

sql 复制代码
EXPLAIN SELECT
  name,
  price
FROM
  products
WHERE
  discontinued = TRUE
  AND price < 100;

输出:

sql 复制代码
                         QUERY PLAN
------------------------------------------------------------
 Seq Scan on products  (cost=0.00..11.75 rows=23 width=532)
   Filter: (discontinued AND (price < '100'::numeric))

PostgreSQL 分部索引的好处

部分索引具有以下优点:

  • 较小的索引大小 -- 部分索引仅采用目标行进行索引。因此,它们占用的磁盘空间更少。
  • 更快的索引扫描和更好的查询性能 -- 当您执行与索引条件匹配的查询时,PostgreSQL 必须扫描较小的索引,这有助于提高查询性能。
  • 减少写入开销并提高查询性能 : 当您插入、更新和删除时,PostgreSQL 必须更新行的子集,从而减少索引更新。

何时使用分部索引

在实践中,您可以在以下场景中使用分部索引:

  • 查询一致包含条件的大型表与部分索引匹配。
  • 筛选条件显著减少了索引的行数,例如活跃用户、实时产品等。

总结

  • 使用部分索引通过仅索引表行的子集来优化查询。
相关推荐
Mr.朱鹏41 分钟前
【Python 进阶 | 第四篇】Psycopg3 + Flask 实现 PostgreSQL CRUD 全流程:从连接池到RESTful接口
python·postgresql·flask·virtualenv·fastapi·pip·tornado
摇滚侠1 小时前
expdp 查看帮助
java·数据库·oracle
流年似水~1 小时前
MCP协议实战:从零搭建一个让Claude能“看见“数据库的工具服务
数据库·人工智能·程序人生·ai·ai编程
2401_871492851 小时前
Vue.js监听器watch利用回调函数处理级联下拉框数据联动
jvm·数据库·python
志栋智能2 小时前
超自动化安全:构建智能安全运营的核心引擎
大数据·运维·服务器·数据库·安全·自动化·产品运营
zhoutongsheng3 小时前
C#怎么实现Swagger文档 C#如何在ASP.NET Core中集成Swagger自动生成API文档【框架】
jvm·数据库·python
WinterKay3 小时前
【开源】我写了一个轻量级本地数据库浏览工具,支持 MySQL/Redis 只读查询
数据库·mysql·开源
zxrhhm4 小时前
Oracle 索引完整指南
数据库·oracle
程序猿乐锅5 小时前
【Tilas|第三篇】多表SQL语句
数据库·经验分享·笔记·学习·mysql
Navicat中国6 小时前
使用 Navicat 导入向导导入 Excel 数据时,系统提示导入成功,表中也能看到数据,但行数统计显示为 0,这是什么原因?
数据库·excel·导入