nma*_*akb 3 postgresql indexing null partial-index
我有一个包含 1m 条记录的表,其中 100k 条记录为 null colA。其余记录具有非常不同的值,在此列上创建常规索引与使用 的部分索引有区别吗where colA is not null?
由于常规 Postgres 索引不存储 NULL 值,那么它不是与使用 创建部分索引相同吗where colA is not null?
这两个指数有什么优点或缺点吗?
如果您创建不带空值的部分索引,则它不会使用它来查找空值。
这是在 13.5 上进行的完整索引测试。
# create index idx_test_num on test(num);
CREATE INDEX
# explain select count(*) from test where num is null;
QUERY PLAN
-------------------------------------------------------------------------------------
Aggregate (cost=5135.00..5135.01 rows=1 width=8)
-> Bitmap Heap Scan on test (cost=63.05..5121.25 rows=5500 width=0)
Recheck Cond: (num IS NULL)
-> Bitmap Index Scan on idx_test_num (cost=0.00..61.68 rows=5500 width=0)
Index Cond: (num IS NULL)
(5 rows)
Run Code Online (Sandbox Code Playgroud)
并带有部分索引。
# create index idx_test_num on test(num) where num is not null;
CREATE INDEX
# explain select count(*) from test where num is null;
QUERY PLAN
--------------------------------------------------------------------------------------
Finalize Aggregate (cost=10458.12..10458.13 rows=1 width=8)
-> Gather (cost=10457.90..10458.11 rows=2 width=8)
Workers Planned: 2
-> Partial Aggregate (cost=9457.90..9457.91 rows=1 width=8)
-> Parallel Seq Scan on test (cost=0.00..9352.33 rows=42228 width=0)
Filter: (num IS NULL)
(6 rows)
Run Code Online (Sandbox Code Playgroud)
由于常规 postgres 索引不存储 NULL 值...
自 16 年前的 8.2 版 [检查注释] 以来,情况并非如此。8.2 文档说...
默认情况下,IS NULL 子句不使用索引。在这种情况下使用索引的最佳方法是使用 IS NULL 谓词创建部分索引。
8.3 引入了 nulls first围绕nulls last空值的许多其他改进,包括......
允许 col IS NULL 使用索引 (Teodor)