索引的分类
BTree适合用于等值查询和范围查询
HASH只能处理等值查询
GiST不是单独的一种索引类型,而是一种架构
SP-GiST空间分区GiST索引
GIN反转索引
创建索引
在创建索引的过程中会把表的数据全部读一遍,该过程所用时间有表的大小决定,在创建索引的过程中,对表的查询可以正常运行,但是对表的增,删,改等操作需要等索引完成后才能进行。
创建一个表
postgres=# create table contacts(
postgres(# id int primary key,
postgres(# name varchar(40),
postgres(# phone varchar(32)[],
postgres(# address text
postgres(# );
CREATE TABLE
创建一个B树索引
postgres=#
postgres=# create index idx_contacts_name on contacts(name);
CREATE INDEX
由于phone字段是一个数组,BTree将不生效,可以建GIN索引
postgres=# create index idx_contacts_phone on contacts using gin(phone);
CREATE INDEX
postgres=# select * from contacts where phone @> array['1343213213'::varchar(32)];
id | name | phone | address
----+------+-------+---------
(0 rows)
@> 是数组操作符,表示包含,GIN索引能在@>上起作用。
HASH索引的更新不会记录到WAL日志中,所以在实际场景中应用的比较少。
create index idx_contacts_name on contacts(name) with (FILLFACTOR=50);
也可以使用降序创建索引
create index idx_contacts_name on contacts(name desc);
字段name中有空值,可以在创建索引时指定空值排在非空值前面
create index idx_contacts_name on contacts(name desc nulls first);
也可以指定空值在非空值后面
create index idx_contacts_name on contacts(name desc nulls last);
并发创建索引
在创建索引的时候,PG会锁定表以防止写入,然后对表做全表扫描,从而完成创建索引的操作,在此过程中,其他用户仍然可以读取表,但是插入,更新,删除等操作将一直被阻塞,直到索引创建完毕。如果这张表是更新比较频繁且比较大的表,那么创建索引可能需要及时分钟,甚至数小时,这段时间内都不能做任何插入,删除,更新操作。
因此,pg支持在不长时间阻塞更新的情况下创建索引,这是通过在create index中加入concurrently选项来试下。
create index concurrently idx_testtab01_note on testtable(note);
此种方式创建索引可以在表上同时进行DML操作,不阻塞。
重建索引不支持concurrently选项,但是在pg中同个字段可以建两个索引,使用concurrently选项建一个新的索引,然后把旧的索引删除掉。
索引失效
\d查看表结构,如果看到索引后面显示INVALID索引可以通过删除
drop index *****;解决
修改索引
索引重命名
alter index idx_name rename to idx_name_old;
索引移动表空间
alter index idx_name set tablespace tbs_data01;
删除索引
drop index idx_name cascade;
删除掉依赖这个索引的对象