2017-09-10 39 views
11

Dizüstü bilgisayarımda bir PostgreSQL 9.6.4 çalıştıran bir birincil anahtar id alanı ve properties::jsonb alanı olan bir tablo var.JSON alanı kullanırken sorgulama optimizasyonu

properties alanında bir GIN dizin ayarı var.

ben bu sorguyu çalıştırdığınızda: ~ 5M satırlar masaya

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; 

bir cevap almak için yaklaşık 20 saniye sürer.

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)) 

Ama ne zaman ben dizini kullanarak optimize edici görüyorum sipariş kaldırın: açıklamak planına bakıldığında sorgu iyileştirici ilk properties alana göre filtreleme sonra birincil anahtar ile tablo sıralama ve öğrendim beklendiği gibi: Ayrıca

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) 

, basit WHERE properties @> '{"slug":"wild-castles"}'::JSONB davranacağını beklendiği gibi:

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) 

yüzden ben niye wo merak ediyorum tahmin optimiz Optimizer, ilk önce satırları filtrelemek ve daha sonra id alanından sipariş vermek için endeksi kullanmaz mı?

+0

Basit bir '' özellikler '>' {"sülük": "wild-castles"} ':: JSONB' için tahminler nelerdir? – teppic

+0

Soruyu güncelledim. – acohen

+0

Düğümlerin yüzde kaçının "sümüklü" alanı var? Bu düğümlerin yüzde kaçı "yabani kaleler" değeriyle "sümüklü" bir özniteliğe sahiptir. – teppic

cevap

1

Değişim Planner Method Configuration ve kuvvet rende yapmamaya seqscan

örn

 SET enable_seqscan = OFF; 

     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; 
1

Tecrübelerime göre, bazen iyi performans elde etmek için sorgu planlayıcısı kandırmak için var ve biraz oynanması alır ve ile ... işe yaramaz

Ben, performansını görmek için bu denemenizi istiyoruz:

SELECT nn.* FROM (
    SELECT n.* 
    FROM node n 
    WHERE node_type_id = '2' 
    AND properties @> '{"slug":"wild-castles"}'::JSONB 
) nn 
ORDER BY nn.id ASC OFFSET 0 LIMIT 10;