Chạy PostgreSQL 9.6.4 trên máy tính xách tay của tôi, tôi có một bảng có tên là node
có khóa chính là id
và trường properties::jsonb
.Tối ưu hóa truy vấn khi sử dụng trường JSON
Tôi có thiết lập chỉ mục GIN trên trường properties
.
Khi tôi chạy truy vấn này:
SELECT n.*
FROM node n
WHERE node_type_id = '2'
AND properties @> '{"slug":"wild-castles"}'::JSONB
ORDER BY n.id ASC OFFSET 0 LIMIT 10;
trên ~ 5M bảng hàng phải mất khoảng 20 giây để có được một câu trả lời. Nhìn vào kế hoạch giải thích tôi phát hiện ra tôi ưu truy vấn là lần đầu tiên sắp xếp bảng theo khóa chính và sau đó lọc theo các properties
lĩnh vực:
Limit (cost=0.56..1517.94 rows=10 width=154)
-> Index Scan using node_pkey on node n (cost=0.56..739571.11 rows=4874 width=154)
Filter: ((properties @> '{"slug": "wild-castles"}'::jsonb) AND ((node_type_id)::text = '2'::text))
Nhưng khi tôi loại bỏ các đặt hàng tôi nhìn thấy tôi ưu hoa bằng cách sử dụng chỉ số như mong đợi:
SELECT n.*
FROM node n
WHERE node_type_id = '2'
AND properties @> '{"slug":"wild-castles"}'::JSONB
OFFSET 0 LIMIT 10;
Limit (cost=93.77..127.10 rows=10 width=154)
-> Bitmap Heap Scan on node n (cost=93.77..16338.56 rows=4874 width=154)
Recheck Cond: (properties @> '{"slug": "wild-castles"}'::jsonb)
Filter: ((node_type_id)::text = '2'::text)
-> Bitmap Index Scan on node_ix02 (cost=0.00..92.55 rows=4874 width=0)
Index Cond: (properties @> '{"slug": "wild-castles"}'::jsonb)
Ngoài ra, một đơn giản WHERE properties @> '{"slug":"wild-castles"}'::JSONB
cư xử như mong đợi:
EXPLAIN SELECT n.*
FROM node n
WHERE properties @> '{"slug":"wild-castles"}'::JSONB
;
Bitmap Heap Scan on node n (cost=93.77..16326.38 rows=4874 width=154)
Recheck Cond: (properties @> '{"slug": "wild-castles"}'::jsonb)
-> Bitmap Index Scan on node_ix02 (cost=0.00..92.55 rows=4874 width=0)
Index Cond: (properties @> '{"slug": "wild-castles"}'::jsonb)
vì vậy, tôi đoán tôi đang tự hỏi tại sao wo uld trình tối ưu hóa không sử dụng chỉ mục để lọc ra các hàng đầu tiên và sau đó sắp xếp chúng theo trường id
?
Các ước tính cho một đơn giản 'nơi các thuộc tính @> '{" slug ":" wild-castles "}' :: JSONB' là gì? – teppic
Tôi đã cập nhật câu hỏi. – acohen
Phần trăm nút nào có trường "slug"? Phần trăm của các nút đó có thuộc tính "slug" với giá trị "wild-castles". – teppic