news 2026/6/10 17:06:08

5.PG基础之索引

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
5.PG基础之索引

索引介绍

索引是数据库中的一种快速查询数据的方法。索引中记录了表中的一列或多列值与其物理位置之间的对应关系,就好比是一本书前面的目录,通过目录中页码就能快速定位到我们需要查询的内容。

索引的代价

  • 增加了数据库的存储空间
  • 在插入和修改数据时要花费较多的时间,因为索引也要随之更新

索引其他用途

除了加快查询以外,比如唯一索引还可以起到唯一约束的作用。


索引的分类

  1. BTree:最常用的索引,适合用于处理等值查询和范围查询。
  2. HASH:只能处理简单的等值查询。
  3. GiST:不是单独一种索引类型,而是一种架构,可以在这种架构上实现很多不同的索引策略。
  4. SP-GiST:即空间分区 GiST 索引,PostgreSQL 9.2 引入。
  5. GIN:反转索引,可以处理包含多个键的值。

创建索引

案例表结构

CREATETABLEcontacts(idintPRIMARYKEY,namevarchar(40),phonevarchar(32)[],addresstext);

1. 简单 BTree 索引

为了实现按姓名name快速查询,可以在字段name上建一个 BTree 索引:

CREATEINDEXidx_contacts_nameONcontacts(name);

2. GIN 索引(用于数组字段)

如果想按电话号码phone字段做快速查询(例如查询某个电话号码是谁的),由于此字段是一个数组,BTree 索引不再适用,可以建一个 GIN 索引:

CREATEINDEXidx_contacts_phoneONcontactsUSINGgin(phone);

查询示例:

SELECT*FROMcontactsWHEREphone @>ARRAY['13422334455'::varchar(32)];

解释:@>是数组操作符,表示“包含”的意思,GIN 索引能在@>上起作用。


创建索引时带参数

CREATEINDEXidx_contacts_nameONcontacts(name)WITH(FILLFACTOR=50);

按降序创建索引

CREATEINDEXidx_contacts_nameONcontacts(nameDESC);

指定空值排序

-- 空值排在非空值前面CREATEINDEXidx_contacts_nameONcontacts(nameDESCNULLSFIRST);-- 空值排在非空值后面CREATEINDEXidx_contacts_nameONcontacts(nameDESCNULLSLAST);

并发创建索引

默认方式的问题

默认情况下,创建索引时会锁定表以防止写入,然后对表做全表扫描。在此过程中:

  • 其他用户可以读取表
  • 插入、更新、删除等操作将一直被阻塞,直到索引创建完毕

示例

CREATETABLEtesttab01(idintPRIMARYKEY,noteint);INSERTINTOtesttab01SELECTgenerate_series(1,5000000),generate_series(1,5000000);

在一个窗口中创建索引:

CREATEINDEXidx_testtab01_noteONtesttab01(note);

在另一个窗口中执行删除操作将被阻塞:

DELETEFROMtesttab01WHEREid=1;

使用CONCURRENTLY选项创建索引

这种方式不会长时间阻塞 DML 操作,但耗时更长,因为需要两次扫描表。

示例

DROPINDEXIFEXISTSidx_testtab01_note;CREATEINDEXCONCURRENTLY idx_testtab01_noteONtesttab01(note);

另一个窗口的删除语句可以正常执行:

DELETEFROMtesttab01WHEREid=2;DELETEFROMtesttab01WHEREid=3;

并发创建索引的“坑”

如果在并发创建索引过程中取消操作,可能会导致索引残留(状态为INVALID)。

处理方法

-- 查看表结构,确认无效索引\d testtab01-- 手动删除无效索引DROPINDEXidx_testtab01_note;

修改索引

重命名索引

ALTERINDEXidx_contacts_nameRENAMETOidx_contacts_name_old;

移动索引到指定表空间

ALTERINDEXidx_contacts_name_oldSETTABLESPACEtbs_data01;

修改填充因子

ALTERINDEXidx_contacts_name_oldSET(fillfactor=75);

查看索引信息

\d+idx_contacts_name_old

删除索引

安全删除(存在才删除)

DROPINDEXIFEXISTSidx_contacts_name_old;

默认RESTRICT行为

如果有对象依赖该索引,删除会失败。

示例

CREATETABLEclass(class_noint,class_namevarchar(40));CREATEUNIQUEINDEXindex_unique_class_noONclass(class_no);CREATETABLEstudent(student_nointPRIMARYKEY,student_namevarchar(40),ageint,class_nointREFERENCESclass(class_no));-- 删除索引会失败,因为有外键依赖DROPINDEXindex_unique_class_no;

使用CASCADE强制删除

DROPINDEXindex_unique_class_noCASCADE;

注意:使用CASCADE会同时删除依赖该索引的外键约束。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 15:23:31

用Tesseract OCR快速搭建证件识别原型系统

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 快速开发一个证件识别原型系统,功能包括:1. 身份证/驾驶证关键信息提取;2. 简单的Web上传界面;3. 结构化数据输出;4. 基…

作者头像 李华
网站建设 2026/6/9 18:42:30

1小时验证eSIM商业创意:快马平台原型开发实战

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 快速开发一个旅行用eSIM服务原型,验证以下功能:1. 用户通过Web选择目的地国家/运营商;2. 系统生成定制eSIM配置文件;3. 手机扫码即可…

作者头像 李华
网站建设 2026/6/1 20:56:50

【VSCode搜索效率翻倍秘籍】:3步解决全局搜索无结果难题

第一章:VSCode全局搜索无结果的常见现象在使用 Visual Studio Code 进行开发时,全局搜索(CtrlShiftF)是定位代码、查找配置项或排查问题的重要手段。然而,许多用户反馈在执行全局搜索时无法返回预期结果,甚…

作者头像 李华
网站建设 2026/6/6 15:16:01

IP(Internet Protocol)协议的出现是计算机网络发展史上的重要里程碑,它的诞生源于特定的历史背景和技术需求。以下从多个方面详细分析IP协议出现的原因:一、军事需求与ARPANET的诞请

IP(Internet Protocol)协议的出现是计算机网络发展史上的重要里程碑,它的诞生源于特定的历史背景和技术需求。以下从多个方面详细分析IP协议出现的原因:一、军事需求与ARPANET的诞生IP协议最早起源于20世纪60年代末美国国防部高级研究计划署(ARPA)的ARPA…

作者头像 李华
网站建设 2026/6/10 12:30:22

Conv2D开发效率对比:传统编码vsAI辅助

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 请生成一份详细的对比报告,包含:1. 手动编写标准Conv2D网络的时间统计 2. 使用AI生成相同功能代码的时间统计 3. 代码质量对比分析 4. 性能测试结果 5. 开发…

作者头像 李华
网站建设 2026/6/10 14:31:18

MELIS3.0开发新纪元:AI如何助力嵌入式系统开发

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 开发一个基于MELIS3.0的智能家居控制模块,要求:1. 使用Kimi-K2模型生成基础框架代码;2. 实现温湿度传感器数据采集功能;3. 包含Wi-F…

作者头像 李华