我有一个相对较小的表(大约50k行)。当我选择所有记录时,需要大约40秒。该表有3个JSONB列。当我选择除JSONB之外的每一列时,查询大约需要700ms。
如果我只添加一个JSONB字段,查询时间就会跳到近10秒。
我从不使用where子句引用JSONB中的内容,只选择*。尽管如此,我还是尝试添加了GIN索引,因为我经常看到它们被认为是JSONB的性能助推器。
我已经运行了一个全真空系统。
Postgres版本9.6
explain (analyze, buffers) select * from message;
Seq Scan on message (cost=0.00..5541.69 rows=52969 width=834) (actual
time=1.736..116.183 rows=52969 loops=1)
Buffers: shared hit=64 read=4948
Planning time: 0.151 ms
Execution time: 133.555 ms发布于 2018-09-07 12:17:06
Jsonb是TOAST varlena数据类型-这意味着当值大于2KB时,它将存储在辅助表(名为PostgreSQL表)中。指向TOAST表的指针存储在主表中。所以当你没有接触到Jsonb列时,这个值就不会被读取。
在这种情况下,GIN索引没有帮助。它只对搜索有帮助。
50K值上的10秒是很长的时间--可能你的Jsonb值太长了,或者你的IO系统执行得不好。请检查表的大小,并检查IO的性能。廉价的云机通常有可怕的IO。
速度慢的另一个可能原因是Jsonb数据类型的复杂性。Jsonb是json子对象的序列化树。如果您不需要Jsonb数据类型的一些特殊特性,那么可以使用JSON数据类型。这只是测试(仅在输入时检查JSON格式)。Jsonb的输出比JSONB快,因为JSON在内部是文本的,并且没有任何必要的操作。Jsonb的输出应该是序列化的,这样代价更高。
https://stackoverflow.com/questions/52214221
复制相似问题