我有一个相对较小的表(~50k 行)。当我选择所有记录时,需要大约 40 秒。该表有 3 个 JSONB 列。当我选择除 JSONB 之外的每一列时,查询需要大约 700 毫秒。
如果我只添加 JSONB 字段之一,查询时间会跳到近 10 秒。
我从不使用引用 JSONB 内部内容的 where 子句,只是选择 *. 即便如此,我还是尝试添加 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
Run Code Online (Sandbox Code Playgroud)
Jsonb 是 PostgreSQL varlena 数据类型 - 这意味着当值大于 2KB 时,则将其存储在辅助表(名为 TOAST 表)中。指向 TOAST 表的指针存储在主表中。因此,当您不触摸 Jsonb 列时,则不会读取此值。
在这种情况下,GIN 索引没有帮助。它有助于搜索。
50K 值上的 10 秒很长 - 也许您的 Jsonb 值很长,或者您的 IO 系统表现不佳。请检查表的大小,并检查 IO 的性能。廉价的云机器通常具有可怕的IO。
变慢的另一个可能原因是 Jsonb 数据类型的复杂性。Jsonb 是 json 子对象的序列化树。如果你不需要 Jsonb 数据类型的一些特殊功能,那么使用 JSON 数据类型。这只是测试(仅在输入时检查 JSON 格式)。JSONB 的输出比 Jsonb 更快,因为 JSON 内部是文本,不需要任何操作。Jsonb 的输出应该是序列化的,哪个更贵。
归档时间: |
|
查看次数: |
1798 次 |
最近记录: |