惊奇发现 PosgresSQL btree 索引可以存储空值

今天查阅了PG官网关于索引的知识,上面介绍到了 PG 的 btree 索引可以存储空值,觉得比较奇怪,因为之前了解到 Oracle btree 索引是不存储空值的,下面特做了以下测试,具体如下。

场景: 测试索引是否存储空值。

创建测试表

1
2
skytf=> create table test_7(id integer , name varchar(32));  
CREATE TABLE

创建索引

1
2
skytf=> create index idx_test_7_name on test_7 using btree (name);  
CREATE INDEX

查询索引初始大小

1
2
3
4
5
skytf=> select pg_size_pretty(pg_relation_size('idx_test_7_name'));  
pg_size_pretty
----------------
8192 bytes
(1 row)

插入测试数据

1
2
3
4
5
6
7
8
9
10
11
skytf=> insert into test_7(id) select generate_series(1,100000);  
INSERT 0 100000
skytf=> select * from test_7 limit 5;
id | name
----+------
1 |
2 |
3 |
4 |
5 |
(5 rows)

再次查看索引大小

1
2
3
4
5
skytf=> select pg_size_pretty(pg_relation_size('idx_test_7_name'));  
pg_size_pretty
----------------
2768 kB
(1 row)

说明:上面明显地看出,在向表 test_7 插入数据后,索引也随着增大了,说明索引能够存储空值。

再插入10条数据

1
2
skytf=> insert into test_7 select generate_series(1,10),'francs';  
INSERT 0 10

查看PLAN

skytf=> explain select count(*) from test_7 where name='francs';  
 QUERY PLAN  
------------------------------------------------------------------------------------  
Aggregate (cost=4.28..4.29 rows=1 width=0)  
 -> Index Scan using idx_test_7_name on test_7 (cost=0.00..4.27 rows=1 width=0)  
 Index Cond: ((name)::text = 'francs'::text)(3 rows)

skytf=> explain select count(*) from test_7 where name is not null ;  
 QUERY PLAN  
------------------------------------------------------------------------------------  
Aggregate (cost=4.28..4.29 rows=1 width=0)  
 -> Index Scan using idx_test_7_name on test_7 (cost=0.00..4.27 rows=1 width=0)  
 Index Cond: (name IS NOT NULL)  
(3 rows)

从上面可以看出,空值也能走索引。

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/236369.html

(0)
上一篇 2022年1月24日
下一篇 2022年1月24日

相关推荐

发表回复

登录后才能评论