PostgreSQL indexing JSONB array
这是我的json
1 2 3 4 5 6 7 | jsondata ------------------------------------ {"key1": 1,"keyset": [10, 20, 30]} {"key1": 1,"keyset": [10, 20]} {"key1": 1,"keyset": [30]} {"key1": 1 } {"key1": 1,"key2": 1} |
我尝试为上面的例子创建索引
使用btree的第一个索引
1 | CREATE INDEX test_keyset ON test_table (jsondata->'keyset'); |
第二个指数使用杜松子酒
1 | CREATE INDEX test_keyset ON test_table USING GIN(jsondata->'keyset'); |
和查询选择
1 2 3 4 5 | SELECT jsondata FROM test JOIN LATERAL jsonb_array_elements_text(jsondata->'keyset') a(v) ON TRUE WHERE a.v::INTEGER = 10; |
但它正在进行顺序扫描(检查所有行),任何人都可以建议我使用哪种索引方法是正确的(btree或gin)以及使用索引从json获取数据的有效方法,例如,我是postgres的新手
在表达式
1 | CREATE INDEX test_keyset ON test USING gin((jsondata->'keyset')); |
您应该将查询中的表达式与
1 2 3 4 5 6 7 8 9 | SELECT jsondata FROM test WHERE jsondata->'keyset' @> '10' jsondata ------------------------------------- {"key1": 1,"keyset": [10, 20, 30]} {"key1": 1,"keyset": [10, 20]} (2 ROWS) |
测试规划者是否可以使用索引:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | SET enable_seqscan TO off; EXPLAIN analyse SELECT jsondata FROM test WHERE jsondata->'keyset' @> '10' QUERY PLAN -------------------------------------------------------------------------------------------------------------------- Bitmap Heap Scan ON test (cost=8.00..12.02 ROWS=1 width=55) (actual TIME=0.024..0.025 ROWS=2 loops=1) Recheck Cond: ((jsondata -> 'keyset'::text) @> '10'::jsonb) Heap Blocks: exact=1 -> Bitmap INDEX Scan ON test_keyset (cost=0.00..8.00 ROWS=1 width=0) (actual TIME=0.014..0.014 ROWS=2 loops=1) INDEX Cond: ((jsondata -> 'keyset'::text) @> '10'::jsonb) Planning TIME: 0.576 ms Execution TIME: 0.066 ms (7 ROWS) |