postgresql中的索引

create table t(k serial primary key, v integer);

这个语句会生成一个序列和一个索引,真实的sql语句如下:

CREATE TABLE public.t
(
  k integer NOT NULL DEFAULT nextval('t_k_seq'::regclass),
  v integer,
  CONSTRAINT t_pkey PRIMARY KEY (k)
)
WITH (
  OIDS=FALSE
);

看到生成了t_k_seq的序列和t_pkey的约束


在v上创建索引

create index i on t (v);

explain analyze select count(*) from t where k>9000 and v=5;

"Aggregate  (cost=808.92..808.93 rows=1 width=0) (actual time=3.542..3.542 rows=1 loops=1)"
"  ->  Bitmap Heap Scan on t  (cost=190.67..785.82 rows=9239 width=0) (actual time=1.038..3.025 rows=9189 loops=1)"
"        Recheck Cond: (v = 5)"
"        Filter: (k > 9000)"
"        Rows Removed by Filter: 919"
"        Heap Blocks: exact=443"
"        ->  Bitmap Index Scan on i  (cost=0.00..188.36 rows=10143 width=0) (actual time=0.785..0.785 rows=10108 loops=1)"
"              Index Cond: (v = 5)"
"Planning time: 0.095 ms"
"Execution time: 3.603 ms"

create index i_combine on t(k,v);

执行上面的语句后,执行计划走的是一样的,

explain analyze select count(*) from t where k=9000 and v=5;

这个的执行计划用到了新建的组合索引

"Aggregate  (cost=8.31..8.32 rows=1 width=0) (actual time=0.044..0.044 rows=1 loops=1)"
"  ->  Index Only Scan using i_combine on t  (cost=0.29..8.31 rows=1 width=0) (actual time=0.041..0.041 rows=0 loops=1)"
"        Index Cond: ((k = 9000) AND (v = 5))"
"        Heap Fetches: 0"
"Planning time: 0.340 ms"
"Execution time: 0.076 ms"

以yaml方式查看执行计划

explain (format yaml)select * from customers where customerid>1000 order by zip;


要查看缓冲区中的信息

explain (analyze on,buffers on) select count(*) from t where v=5;


"Aggregate  (cost=786.05..786.06 rows=1 width=0) (actual time=2.885..2.885 rows=1 loops=1)"
"  Buffers: shared hit=473"
"  ->  Bitmap Heap Scan on t  (cost=190.90..760.69 rows=10143 width=0) (actual time=0.765..2.328 rows=10108 loops=1)"
"        Recheck Cond: (v = 5)"
"        Heap Blocks: exact=443"
"        Buffers: shared hit=473"
"        ->  Bitmap Index Scan on i  (cost=0.00..188.36 rows=10143 width=0) (actual time=0.699..0.699 rows=10108 loops=1)"
"              Index Cond: (v = 5)"
"              Buffers: shared hit=30"
"Planning time: 0.090 ms"
"Execution time: 2.929 ms"


explain analyze select count(*) from tt where v  is null;

"Aggregate  (cost=8.27..8.28 rows=1 width=0) (actual time=0.092..0.092 rows=1 loops=1)"
"  ->  Index Only Scan using it_v on tt  (cost=0.29..8.27 rows=1 width=0) (actual time=0.086..0.088 rows=1 loops=1)"
"        Index Cond: (v IS NULL)"
"        Heap Fetches: 1"
"Planning time: 0.070 ms"
"Execution time: 0.117 ms"

排序索引

create index i_order on t(v desc nulls first);

部分索引:只对部分的记录进行索引

函数索引:同oracle


聚集索引:待了解

pg中的索引,可以在同一个列上定义2个索引,这样在重建索引的时候,可以按下面的方式去执行:



create table test(id integer primary key, category text,value text);
create index  test_category_idx on test(category);
create index concurrently new_index on test(category);
begin;
drop index test_category_idx;
alter index new_index rename to test_category_idx;
commit;


create index concurrently 允许索引在被创建的时候执行dml语句

查看未使用的索引

select schemaname,relname,indexrelname,idx_scan from pg_stat_user_indexs order by idx_scan;

重建索引
1在操作系统上使用reindexdb -u postgres -d postgres

为了避免删除索引后,发现索引还有用,能够快速的让索引正常工作,我们可以使用下面的方式来操作

1CREATE OR REPLACE FUNCTION trial_drop_index(iname TEXT)
RETURNS VOID
LANGUAGE SQL AS $$
UPDATE pg_index
SET indisvalid = false
WHERE indexrelid = $1::regclass;
$$;

运行这个函数来模拟删除索引,如果发现索引还有用,使用下面的函数恢复索引

CREATE OR REPLACE FUNCTION trial_undrop_index(iname TEXT)
RETURNS VOID
LANGUAGE SQL AS $$
UPDATE pg_index
SET indisvalid = true
WHERE indexrelid = $1::regclass;
$$;

这个就是设置索引是否有效,与oracle是一样的

重命名索引

alter index idx_contacts_name rename to idx_contacts_name_old;

alter index idx_contacts_name_old set tablespace tbs_data01;

将索引的填充因子设置成默认值

alter index idx_contacts_name reset(fillfactor);

查看索引信息

\d+ idx_contacts_name_old

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值