Postgres-这是在布尔列创建部分索引的正确方法吗?
技术问答
269 人阅读
|
0 人回复
|
2023-09-14
|
我有下表:
' D' ?) C# E2 M/ D' DCREATE TABLE recipemetadata( --Lots of columns diet_glutenfree boolean NOT NULL,);FALSE除非有人提出一些疯狂的新无麸质饮食来席卷全国,否则在大多数情况下,每一行都会被设定为。) W0 `; Q) i" _( {0 l7 @/ V
我需要能够快速查询值true行。我创建了索引:# o: e `$ n/ a' c) X& @0 ~! N7 C4 q
CREATE INDEX IDX_RecipeMetadata_GlutenFree ON RecipeMetadata(diet_glutenfree) WHERE diet_glutenfree;它似乎可以工作,但我不知道如何确定索引值是否仅为true是的。我想确保它不会像索引任何值那样愚蠢。
, q9 M. r3 ?7 }+ ^! t1 g4 Y我应该在WHERE在句子中添加运算符,还是语法完全有效?希望这不是那些会被拒绝30次的超级简单RTFM问题之一。
# W! M' A7 d# A更新:2 y4 ~" O9 O, M
我继续,并向RecipeMetadata加1万行随机值。然后我在桌子上做了一个分析,然后做了一个REINDEX来确定吧。运行查询时:
: K* F: @- |9 nselect recipeid from RecipeMetadata where diet_glutenfree;
% k& Y& I* n$ R' ~) R( i我得到:5 t6 ^* r, Q% U, u8 d Y ?3 B2 }
'Seq Scan on recipemetadata (cost=0.00..214.26 rows=5010 width=16)'' Filter: diet_glutenfree'因此,即使只有大约一半的行有这个标志,它似乎仍在按顺序扫描表。索引被忽略了。
8 N3 q9 Q" j8 q1 y! a4 c/ n- J( p N如果我做:4 s' X4 E. |* X9 F8 V
select recipeid from RecipeMetadata where not diet_glutenfree;& ^# Z8 ^ |4 r0 I& T4 H# d
我得到:
, I- z& M0 a2 e0 H0 Y5 W4 M! u1 z'Seq Scan on recipemetadata (cost=0.00..214.26 rows=5016 width=16)'' Filter: (NOT diet_glutenfree)'因此,无论如何,索引都不会使用。/ j9 G! G; I. {/ O1 h
' ` J# f( J m" `- }* M& G 解决方案:
4 ^; G5 f/ P+ J 我已经确认索引可以正常工作。2 r3 Q! Q* H, F/ `4 x
我重新创建了随机数据,只是这次设置为零diet_glutenfree,random() > 0.9所以只有10%的几率on。
7 |% U9 o7 |4 X2 w然后,我重新创建了索引,然后再次尝试查询。! ]1 L; v1 ?4 g5 x; O* B
SELECT RecipeId from RecipeMetadata where diet_glutenfree;返回值:
& G& q9 A& Q+ M+ Q'Index Scan using idx_recipemetadata_glutenfree on recipemetadata (cost=0.00..135.15 rows=1030 width=16)'' Index Cond: (diet_glutenfree = true)'和:
6 r) F/ T4 x1 ?SELECT RecipeId from RecipeMetadata where NOT diet_glutenfree;返回值:
8 K# a* s& v( v$ X'Seq Scan on recipemetadata (cost=0.00..214.26 rows=8996 width=16)'' Filter: (NOT diet_glutenfree)'我的第一次尝试似乎被污染了,因为PG据估计,如果它必须加载一半以上的行,扫描整个表比击中索引要快。
8 j6 f0 o; o9 H9 _% Q, a/ x但是,我想我会在这个列的完整索引中得到这些确切的结果。有没有办法验证在某些索引中建立索引的行数?7 z1 x; m9 N# f) s8 i; o
更新
9 J4 x1 l/ L' N3 U5 t2 k该指数约为40k。我创建了同一列的完整索引,索引超过200个k,所以看起来绝对是部分索引。 |
|
|
|
|
|