Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 在JSONB列上添加GIN索引会减慢我的请求_Postgresql_Indexing_Jsonb_Gwt Gin - Fatal编程技术网

Postgresql 在JSONB列上添加GIN索引会减慢我的请求

Postgresql 在JSONB列上添加GIN索引会减慢我的请求,postgresql,indexing,jsonb,gwt-gin,Postgresql,Indexing,Jsonb,Gwt Gin,我来自Mysql和nosql数据库,我是Postgress db的新手。我正在Aurora AWS上使用Postgres 11.6 我试图创建由两列组成的表,一个键和一个jsonb值 每个值如下所示: {"game": "game6", "username": "Djobi", (bunch of fields) "permissions": ["permission3", "permission1", "permission5"]} 我试图添加不同的索引,以查看数据库

我来自Mysql和nosql数据库,我是Postgress db的新手。我正在Aurora AWS上使用Postgres 11.6

我试图创建由两列组成的表,一个键和一个jsonb值

每个值如下所示:

{"game": "game6",
   "username": "Djobi",   
   (bunch of fields)
   "permissions": ["permission3", "permission1", "permission5"]}
我试图添加不同的索引,以查看数据库的容量。其中之一,就是通过用户名查找用户。另一个是查找具有特定权限的用户

account_index | account_index | username |在public.account_index上创建索引account_index_username |使用btree(((value->“username”::text))进行索引)
account_index | account_index | permissions |在public.account_索引上创建索引account_index(使用gin(((值->‘权限’::text))的权限)
account_index | account_global_gin |使用gin(值)在public.account_索引上创建索引accountgin
我有两张表,数据完全相同。每个表大约有3000万行。一个有索引,一个没有。我正在运行以下查询以测试性能:

SELECT 1 
FROM account_noindex 
WHERE value @> '{"permissions": ["permission1"]}' limit 10;
我在这里尝试查找具有权限1的用户。(旁注,尚不确定如何询问具体许可1与包括许可1在内的任何许可) 在索引表上运行请求时,响应时间为5000ms。 在我的非索引表上运行请求时,我得到了50毫秒的响应时间

所以非索引表比索引表快100倍,这让我很困惑。 如果我尝试对这两个查询进行解释,我会得到以下结果:

索引表:

限制(成本=430.49..468.31行=10宽=32)
->帐户索引上的位图堆扫描(成本=430.49..144146.44行=37999宽度=32)
重新检查条件:(值@>'{“权限”:[“权限1”]}'::jsonb)
->accountgin上的位图索引扫描(成本=0.00..420.99行=37999宽度=0)
索引条件:(value@>'{“permissions”:[“permission1”]}'::jsonb)
(5排)
非索引表

限制(成本=0.00..1935.23行=10宽=4)
->按账户扫描索引(成本=0.00..7360637.42行=38035宽度=4)
筛选器:(值@>'{“权限”:[“权限1”]}'::jsonb)
如果我尝试深入偏移量(100k以上),差异就不那么明显了,但非索引表仍然更快

[编辑] 以下是索引表的完整分析缓冲区:

EXPLAIN (ANALYZE, BUFFERS) SELECT value->'permissions' FROM account_index WHERE value @> '{"permissions": ["permission1"]}' limit 12;
                                                                QUERY PLAN                                                                 
-------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=430.49..475.88 rows=12 width=32) (actual time=1926.289..1926.365 rows=12 loops=1)
   Buffers: shared hit=24398
   ->  Bitmap Heap Scan on account_index  (cost=430.49..144146.44 rows=37999 width=32) (actual time=1926.287..1926.361 rows=12 loops=1)
         Recheck Cond: (value @> '{"permissions": ["permission1"]}'::jsonb)
         Rows Removed by Index Recheck: 30
         Heap Blocks: lossy=8
         Buffers: shared hit=24398
         ->  Bitmap Index Scan on accountgin  (cost=0.00..420.99 rows=37999 width=0) (actual time=1916.655..1916.656 rows=8386144 loops=1)
               Index Cond: (value @> '{"permissions": ["permission1"]}'::jsonb)
               Buffers: shared hit=24390
 Planning Time: 0.073 ms
 Execution Time: 1927.143 ms

那么我在这里错过了什么?我是否错误地创建了GIN索引?还是我的请求做错了?


注意,我的用户名上的索引也有同样的问题。在请求查找具有特定用户名的用户时,无论是否使用GIN索引,我都会得到一个完整的表扫描。当我添加BTREE索引时,没有问题,也不需要限制。

JSONB列没有收集到有用的统计数据。该数据库必须对满足@>的行数进行一般性假设,而这些假设通常是错误的。在决定进行限额查询的绝对最佳方式时,拥有更准确的统计信息非常重要。一般的假设是@>将匹配表的0.1%。如果这对你的情况来说是严重错误的,你很可能会得到糟糕的计划

尽管两个计划之间的差异看起来确实非常大。如果没有SEED
解释(分析、缓冲)
就很难具体说明这一点

注意,我的用户名上的索引也有同样的问题。如果我只是有杜松子酒指数,我会得到非常奇怪的结果。当我添加BTREE索引时,就没有问题了


我不知道“奇怪”的结果可能是什么。你必须提供一些例子。

谢谢,我编辑了原文来解释另一个奇怪之处。我想原因和你解释的差不多。我还添加了分析。