PostgreSQL索引详解:类型、创建与实践
索引是加速搜索引擎检索数据的一种特殊表查询。简单地说,索引是一个指向表中数据的指针。一个数据库中的索引与一本书的索引目录是非常相似的。
拿汉语字典的目录页(索引)打比方,我们可以按拼音、笔画、偏旁部首等排序的目录(索引)快速查找到需要的字。
索引有助于加快 SELECT 查询和 WHERE 子句,但它会减慢使用 UPDATE 和 INSERT 语句时的数据输入。索引可以创建或删除,但不会影响数据。
菜鸟教程:PostgreSQL 索引 | 菜鸟教程 (runoob.com)
什么情况下要避免使用索引?
虽然索引的目的在于提高数据库的性能,但这里有几个情况需要避免使用索引。
使用索引时,需要考虑下列准则:
索引不应该使用在较小的表上。
索引不应该使用在有频繁的大批量的更新或插入操作的表上。
索引不应该使用在含有大量的 NULL 值的列上。
索引不应该使用在频繁操作的列上。
创建索引
使用CREATE INDEX
语句创建索引,指定索引名称、索引类型和要索引的列。
CREATE INDEX
(创建索引)的语法如下:
CREATE INDEX index_name ON table_name (column1, column2, ...);
例如,如果你有一个名为employees
的表,并且你经常根据last_name
列进行查询,你可以这样创建一个B-tree索引:
CREATE INDEX idx_employees_lastname ON employees (last_name);
索引类型
单列索引
单列索引是一个只基于表的一个列上创建的索引,基本语法如下:
CREATE INDEX index_name ON table_name (column_name);
组合索引
组合索引是基于表的多列上创建的索引,基本语法如下:
CREATE INDEX index_name ON table_name (column1_name, column2_name);
不管是单列索引还是组合索引,该索引必须是在 WHERE 子句的过滤条件中使用非常频繁的列。
如果只有一列被使用到,就选择单列索引,如果有多列就使用组合索引。
唯一索引
使用唯一索引不仅是为了性能,同时也为了数据的完整性。唯一索引不允许任何重复的值插入到表中。基本语法如下:
CREATE UNIQUE INDEX index_name ON table_name (column_name);
局部索引
局部索引是在表的子集上构建的索引;子集由一个条件表达式上定义。索引只包含满足条件的行。基础语法如下:
CREATE INDEX index_name on table_name (conditional_expression);
隐式索引
隐式索引 是在创建对象时,由数据库服务器自动创建的索引。索引自动创建为主键约束和唯一约束。
查看索引
如果需要查看某个表的索引,使用如下命令:
\d table_name
删除索引
在PostgreSQL中,删除索引是一个相对简单的操作。当你不再需要某个索引时,可能是因为它不再提供性能优势,或者你需要重新设计索引策略,你可以使用DROP INDEX
语句来删除它。
以下是删除索引的基本语法:
DROP INDEX [IF EXISTS] index_name;
其中:
IF EXISTS
是一个可选的子句,如果你不确定索引是否存在,使用这个子句可以避免因为索引不存在而抛出错误。index_name
是你想要删除的索引的名称。
例如,如果你之前创建了一个名为idx_employees_lastname
的索引,并且现在想要删除它,你可以执行以下SQL命令:
DROP INDEX idx_employees_lastname;
或者,如果你不确定索引是否存在:
DROP INDEX IF EXISTS idx_employees_lastname;
删除索引时需要注意以下几点:
性能影响:删除一个索引通常是一个快速的操作,但是如果你在一个非常大的表上删除了一个经常被查询使用的索引,那么查询性能可能会显著下降,因为查询规划器不再能够利用该索引来加速查询。
锁定:在删除索引的过程中,PostgreSQL可能会锁定相关的表。这可能会影响到其他正在运行的查询或事务,特别是在高并发的系统中。
磁盘空间:删除索引会释放它所占用的磁盘空间,但是这个空间不一定会立即返回给操作系统,这取决于PostgreSQL的存储管理和操作系统的行为。
事务性:
DROP INDEX
是一个事务性操作,这意味着它可以在事务中执行,并且如果事务回滚,索引的删除也会被撤销。依赖关系:在删除索引之前,确保没有其他数据库对象(如视图、函数或触发器)依赖于该索引,否则可能会导致错误或使这些对象无效。
备份:在执行任何结构性更改之前,最好先备份你的数据库,以防万一出现意外情况。
重新评估查询性能:在删除索引后,重新评估相关查询的性能,以确保系统的整体性能没有受到负面影响。如果需要,可以考虑创建新的索引来优化性能。
使用索引
当查询条件与索引列匹配时,PostgreSQL查询规划器会自动使用索引。确保你的WHERE
子句、JOIN
条件和ORDER BY
子句能够利用索引。
使用EXPLAIN
语句检查查询的执行计划,确认PostgreSQL是否使用了索引。
EXPLAIN SELECT * FROM employees WHERE last_name = 'Smith';