PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 22/10/2020 14:52:16

Index GIN et égalité

Bonjour,

Je suis tombé sur un comportement étrange avec pg 12.4, je ne sais pas bien si cela relève d'un bug de l'optimiseur PG ou bien de quelque chose qui m'échappe...

J'ai une table avec 10 millions de lignes (propre en terme de VACUUM ANALYZE). Elle comporte un champ "EXTRA" de type JSONB dont l'attribut "celex" est indexé en GIN :

 "ix_ds_document_id_celex" gin ((extra ->> 'id_celex'::text) gin_trgm_ops) WHERE (extra ->> 'id_celex'::text) IS NOT NULL

Si je recherche une ligne en faisant une égalité, il fait un full scan de la table, alors que si je fais un LIKE il utilise bien l'index !?

dev=> explain select id from ds.document where extra->>'id_celex' = 'ABC';
                                   QUERY PLAN                                    
---------------------------------------------------------------------------------
 Gather  (cost=1000.00..2682290.02 rows=50435 width=8)
   Workers Planned: 2
   ->  Parallel Seq Scan on document  (cost=0.00..2676246.52 rows=21015 width=8)
         Filter: ((extra ->> 'id_celex'::text) = 'ABC'::text)
 JIT:
   Functions: 4
   Options: Inlining true, Optimization true, Expressions true, Deforming true
(7 rows)

dev=> explain select id from ds.document where extra->>'id_celex' like 'ABC';
                                         QUERY PLAN                                         
--------------------------------------------------------------------------------------------
 Bitmap Heap Scan on document  (cost=634.87..180484.00 rows=50435 width=8)
   Recheck Cond: ((extra ->> 'id_celex'::text) ~~ 'ABC'::text)
   ->  Bitmap Index Scan on ix_ds_document_id_celex  (cost=0.00..622.26 rows=50435 width=0)
         Index Cond: ((extra ->> 'id_celex'::text) ~~ 'ABC'::text)
 JIT:
   Functions: 4
   Options: Inlining false, Optimization false, Expressions true, Deforming true
(7 rows)

J'aimerais bien comprendre....

Hors ligne

#2 22/10/2020 15:39:08

rjuju
Administrateur

Re : Index GIN et égalité

Bonjour,


Il s'agit du comportement souhaité, car pg_trgm supporte l'opérateur like mais pas l'égalité (vu que ce n'est pas le but) :

=# SELECT c.opcname,
op.amoplefttype::regtype,
op.amoprighttype::regtype,
op.amopopr::regoper
FROM pg_am am
JOIN pg_opfamily f ON f.opfmethod = am.oid
JOIN pg_opclass c ON c.opcfamily = f.oid
JOIN pg_amop op ON op.amopfamily = f.oid
WHERE c.opcname = 'gin_trgm_ops';
   opcname    | amoplefttype | amoprighttype |    amopopr
--------------+--------------+---------------+----------------
 gin_trgm_ops | text         | text          | public.%
 gin_trgm_ops | text         | text          | pg_catalog.~~
 gin_trgm_ops | text         | text          | pg_catalog.~~*
 gin_trgm_ops | text         | text          | pg_catalog.~
 gin_trgm_ops | text         | text          | pg_catalog.~*
 gin_trgm_ops | text         | text          | %>
 gin_trgm_ops | text         | text          | %>>
(7 rows)

Hors ligne

#3 22/10/2020 15:44:29

Re : Index GIN et égalité

Merci de la réponse.

Je trouve cela étrange, puisque je ne vois pas bien la différence entre LIKE 'ABC' et = 'ABC' ...

Hors ligne

#4 23/10/2020 04:52:22

rjuju
Administrateur

Re : Index GIN et égalité

Il n'y a pas de différence dans ce cas particulier effectivement.  J'imagine qu'il serait simple d'ajouter le support pour l'opérateur =, mais que cela n'a jamais été fait car pg_trgm est utilisé pour des recherches type '%pattern%', et les index créés ne sont du coup pas spécialement adapté à une recherche d'égalité (plus volumineux et moins efficaces qu'un simple btree).

Hors ligne

#5 23/10/2020 18:22:39

Re : Index GIN et égalité

Je suis bien d'accord, mais les rares fois où on a besoin d'une recherche exacte, c'est ballot de faire un table scan alors qu'on a un index qui peut bien accélérer les choses (même si c'est pas aussi bien qu'un B-Tree dans ce cas particulier) ;-)

Mais bon, il suffit de le savoir, et on fait du LIKE 'ABC' au lieu de = 'ABC', c'est juste un peu contre-intuitif.

Dernière modification par herve.lefebvre (23/10/2020 18:23:02)

Hors ligne

#6 26/10/2020 06:16:32

rjuju
Administrateur

Re : Index GIN et égalité

Pour information j'ai proposé de gérer ce cas pour gin_trgm_ops et gin_trgm_ops et l'idée est plutôt bienvenue : https://www.postgresql.org/message-id/f … .gmail.com .  J'ai également proposé un patch pour ça, avec un peu de chance cela sera intégré dans la version 14 de postgres.

Hors ligne

#7 26/10/2020 10:18:10

Re : Index GIN et égalité

rjuju a écrit :

Pour information j'ai proposé de gérer ce cas pour gin_trgm_ops et gin_trgm_ops et l'idée est plutôt bienvenue : https://www.postgresql.org/message-id/f … .gmail.com .  J'ai également proposé un patch pour ça, avec un peu de chance cela sera intégré dans la version 14 de postgres.


Cool ;-)

Ça évitera probablement quelques "accidents"...

Hors ligne

#8 27/10/2020 11:42:01

Re : Index GIN et égalité

Bonjour,

Il y a quand même toujours quelque chose qui m'échappe avec ce GIN index et le calcul du plan d'exécution :

Là, pour moi tout est normal :

dev_ds=> explain select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1';
                                             QUERY PLAN                                              
-----------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on document  (cost=2530.38..183518.22 rows=50372 width=50)
   Recheck Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
   ->  Bitmap Index Scan on ix_ds_document_id_cellar  (cost=0.00..2517.79 rows=50372 width=0)
         Index Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
 JIT:
   Functions: 4
   Options: Inlining false, Optimization false, Expressions true, Deforming true
(7 rows)

Pourquoi diable l'ajout de "limit 1" le dissuade d'utiliser l'index ? (enfin là encore je pourrais comprendre si on suppose que le like ramène un % de lignes assez élevé...)

dev_ds=> explain select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1' limit 1;
                                           QUERY PLAN                                            
-------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..61.28 rows=1 width=50)
   ->  Seq Scan on document  (cost=0.00..3086581.90 rows=50372 width=50)
         Filter: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
(3 rows)

Mais pourquoi l'ajout d'un joker (peut importe lequel et peut importe sa position)  va à nouveau faire choisir au planner l'usage de l'index ??

dev_ds=> explain select uri, date from ds.document where extra->>'id_cellar' like '%487d4f99-f65b-11ea-991b-01aa75ed71a1' limit 1;
                                                 QUERY PLAN                                                 
------------------------------------------------------------------------------------------------------------
 Limit  (cost=2051.81..2055.77 rows=1 width=50)
   ->  Bitmap Heap Scan on document  (cost=2051.81..6038.96 rows=1007 width=50)
         Recheck Cond: ((extra ->> 'id_cellar'::text) ~~ '%487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
         ->  Bitmap Index Scan on ix_ds_document_id_cellar  (cost=0.00..2051.56 rows=1007 width=0)
               Index Cond: ((extra ->> 'id_cellar'::text) ~~ '%487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
(5 rows)

Hors ligne

#9 27/10/2020 23:14:39

gleu
Administrateur

Re : Index GIN et égalité

Lorsque vous ne comprenez pas pourquoi il utilise tel nœud plutôt qu'un autre, essayez de le désactiver. Dans le cas présente, faite un "SET enable_seqscan TO off;". Ça ne désactive pas complètement la possibilité d'avoir un parcours séquentiel, mais ça limite très fortement son utilisation.

De plus, quel est la taille de la table et de l'index ? (SELECT pg_table_size('ds.document'), pg_table_size('ix_ds_document_id_cellar'); ... non, il n'y a pas d'erreur dans la requête, c'est bien pg_table_size dans les deux cas).


Guillaume.

Hors ligne

#10 15/11/2020 08:24:08

rjuju
Administrateur

Re : Index GIN et égalité

Bonne nouvelle, le patch a été committé aujourd'hui: https://git.postgresql.org/gitweb/?p=po … e5aa05a066

Le support de l'opérateur = sera donc dispnible avec la version 14.

Hors ligne

#11 20/11/2020 18:16:02

Re : Index GIN et égalité

Super. Merci !

Hors ligne

#12 02/02/2021 15:33:03

SQLpro
Membre

Re : Index GIN et égalité

LIMIT 1 impose un tri. Or les index GIN ne sont pas "triables"

A +


Frédéric Brouard, alias SQLpro,  ARCHITECTE DE DONNÉES,  Expert langage SQL
Le site sur les SGBD relationnel et langage SQL   : http://sqlpro.developpez.com/
Modélisation de données, conseil, expertise, audit, optimisation, tuning, formation
* * * * *  Enseignant CNAM PACA, ISEN Toulon,  CESI Aix en Provence  * * * * *

Hors ligne

#13 02/02/2021 15:38:50

gleu
Administrateur

Re : Index GIN et égalité

Certes, les index GIN ne sont pas triables mais "LIMIT" n'impose pas de tri.


Guillaume.

Hors ligne

#14 02/02/2021 15:42:42

frost242
Administrateur

Re : Index GIN et égalité

D'ailleurs, où voyez-vous un tri dans les plans montrés par M. Lefebvre ?


Thomas Reiss

Hors ligne

#15 02/02/2021 15:45:59

Re : Index GIN et égalité

SQLpro a écrit :

LIMIT 1 impose un tri. Or les index GIN ne sont pas "triables"

Euh non.


aegir=# create table toto(id integer, lib text);
CREATE TABLE
aegir=# insert into toto values (1,'z');
INSERT 0 1
aegir=# insert into toto values (2,'y');
INSERT 0 1
aegir=# insert into toto values (3,'x');
INSERT 0 1
aegir=# select lib from toto;
 lib 
-----
 z
 y
 x
(3 rows)

aegir=# select lib from toto limit 1;
 lib 
-----
 z
(1 row)

aegir=# select id from toto limit 1;
 id 
----
  1
(1 row)

Hors ligne

#16 02/02/2021 21:50:24

SQLpro
Membre

Re : Index GIN et égalité

Comment voulez vous retrouver la première ligne dans un système ensembliste si l'on y met pas un peu d'ordre ?
Certes il n'y a pas de ORDER BY (tri logique), mais il effectue un tri interne (physique) d'une quelconque manière (accès à la PREMIÈRE ligne de la page) pour retrouver l'information...

A +


Frédéric Brouard, alias SQLpro,  ARCHITECTE DE DONNÉES,  Expert langage SQL
Le site sur les SGBD relationnel et langage SQL   : http://sqlpro.developpez.com/
Modélisation de données, conseil, expertise, audit, optimisation, tuning, formation
* * * * *  Enseignant CNAM PACA, ISEN Toulon,  CESI Aix en Provence  * * * * *

Hors ligne

#17 02/02/2021 22:00:36

rjuju
Administrateur

Re : Index GIN et égalité

Non, il faudrait que vous fassiez la différence entre ce que vous imaginez et la réalité.  Je vous suggère donc de suivre vos propre conseils:


sqlpro a écrit :

Bref, commencez par lire, apprendre, vous former à PostgreSQL...

Merci.

Hors ligne

#18 04/02/2021 11:46:05

frost242
Administrateur

Re : Index GIN et égalité

Pour revenir au problème sur le LIMIT   OFFSET 1comme l'a suggéré gleu, pouvez-vous redonner le plan d'exécution de la requête après avoir fait un SET enable_seqscan = off; dans la même session ?


Thomas Reiss

Hors ligne

#19 04/02/2021 11:56:24

Re : Index GIN et égalité

frost242 a écrit :

Pour revenir au problème sur le LIMIT   OFFSET 1comme l'a suggéré gleu, pouvez-vous redonner le plan d'exécution de la requête après avoir fait un SET enable_seqscan = off; dans la même session ?

dev_ds=> explain select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1';
                                             QUERY PLAN                                              
-----------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on document  (cost=3645.60..189304.19 rows=51760 width=50)
   Recheck Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
   ->  Bitmap Index Scan on ix_ds_document_id_cellar  (cost=0.00..3632.66 rows=51760 width=0)
         Index Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
 JIT:
   Functions: 4
   Options: Inlining false, Optimization false, Expressions true, Deforming true
(7 rows)

dev_ds=> explain select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1' limit 1;
                                           QUERY PLAN                                            
-------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..59.71 rows=1 width=50)
   ->  Seq Scan on document  (cost=0.00..3090748.05 rows=51760 width=50)
         Filter: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
(3 rows)

dev_ds=> explain select uri, date from ds.document where extra->>'id_cellar' like '%487d4f99-f65b-11ea-991b-01aa75ed71a1' limit 1;
                                            QUERY PLAN                                            
--------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..2986.23 rows=1 width=50)
   ->  Seq Scan on document  (cost=0.00..3090748.05 rows=1035 width=50)
         Filter: ((extra ->> 'id_cellar'::text) ~~ '%487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
(3 rows)

dev_ds=> SET enable_seqscan = off;
SET
dev_ds=> explain select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1';
                                             QUERY PLAN                                              
-----------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on document  (cost=3645.60..189304.19 rows=51760 width=50)
   Recheck Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
   ->  Bitmap Index Scan on ix_ds_document_id_cellar  (cost=0.00..3632.66 rows=51760 width=0)
         Index Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
 JIT:
   Functions: 4
   Options: Inlining false, Optimization false, Expressions true, Deforming true
(7 rows)

dev_ds=> explain select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1' limit 1;
                                                QUERY PLAN                                                 
-----------------------------------------------------------------------------------------------------------
 Limit  (cost=3645.60..3649.18 rows=1 width=50)
   ->  Bitmap Heap Scan on document  (cost=3645.60..189304.19 rows=51760 width=50)
         Recheck Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
         ->  Bitmap Index Scan on ix_ds_document_id_cellar  (cost=0.00..3632.66 rows=51760 width=0)
               Index Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
(5 rows)

dev_ds=> explain select uri, date from ds.document where extra->>'id_cellar' like '%487d4f99-f65b-11ea-991b-01aa75ed71a1' limit 1;
                                                 QUERY PLAN                                                 
------------------------------------------------------------------------------------------------------------
 Limit  (cost=3497.07..3501.03 rows=1 width=50)
   ->  Bitmap Heap Scan on document  (cost=3497.07..7594.29 rows=1035 width=50)
         Recheck Cond: ((extra ->> 'id_cellar'::text) ~~ '%487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
         ->  Bitmap Index Scan on ix_ds_document_id_cellar  (cost=0.00..3496.81 rows=1035 width=0)
               Index Cond: ((extra ->> 'id_cellar'::text) ~~ '%487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
(5 rows)

Time: 0.939 ms

Dernière modification par herve.lefebvre (04/02/2021 12:00:00)

Hors ligne

#20 04/02/2021 12:18:08

frost242
Administrateur

Re : Index GIN et égalité

Merci. Pouvez-vous essayer avec cette requête, en prenant soin de remettre enable_seqscan à on :

WITH w AS NOT MATERIALIZED (
explain select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1'
)
SELECT * FROM w LIMIT 1;

Vous tombez sur un des problèmes de l'optimiseur de PostgreSQL, où il "suppose" qu'il va trouver très rapidement une ligne qui colle au critère de filtrage.

Une idée, peut-être en l'air, serait de forcer un tri sur le résultat, là Postgres prend l'index pour retrouver la première ligne qui colle :

explain select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1' order by extra->>'id_cellar' limit 1;

Eventuellement, vous ne pouvez pas créer un btree pour voir ?


Thomas Reiss

Hors ligne

#21 04/02/2021 12:34:29

Re : Index GIN et égalité

frost242 a écrit :

Merci. Pouvez-vous essayer avec cette requête, en prenant soin de remettre enable_seqscan à on :

WITH w AS NOT MATERIALIZED (
explain select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1'
)
SELECT * FROM w LIMIT 1;

Vous tombez sur un des problèmes de l'optimiseur de PostgreSQL, où il "suppose" qu'il va trouver très rapidement une ligne qui colle au critère de filtrage.

Une idée, peut-être en l'air, serait de forcer un tri sur le résultat, là Postgres prend l'index pour retrouver la première ligne qui colle :

explain select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1' order by extra->>'id_cellar' limit 1;
dev_ds=> explain WITH w AS NOT MATERIALIZED (                                                                                                                         
select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1'
)
SELECT * FROM w LIMIT 1;
                                           QUERY PLAN                                            
-------------------------------------------------------------------------------------------------
 Limit  (cost=0.00..59.71 rows=1 width=50)
   ->  Seq Scan on document  (cost=0.00..3090748.05 rows=51760 width=50)
         Filter: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
(3 rows)

Time: 1.377 ms
dev_ds=>
dev_ds=> explain select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1' order by extra->>'id_cellar' limit 1;
                                                   QUERY PLAN                                                    
-----------------------------------------------------------------------------------------------------------------
 Limit  (cost=189692.39..189692.39 rows=1 width=82)
   ->  Sort  (cost=189692.39..189821.79 rows=51760 width=82)
         Sort Key: ((extra ->> 'id_cellar'::text))
         ->  Bitmap Heap Scan on document  (cost=3645.60..189433.59 rows=51760 width=82)
               Recheck Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
               ->  Bitmap Index Scan on ix_ds_document_id_cellar  (cost=0.00..3632.66 rows=51760 width=0)
                     Index Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
 JIT:
   Functions: 5
   Options: Inlining false, Optimization false, Expressions true, Deforming true
(10 rows)

Time: 4.387 ms


 

Eventuellement, vous ne pouvez pas créer un btree pour voir ?

Non, ce sont les dernières heures auxquelles j'ai accès à la db.

Pour le fun, la différence entre les 2 :

dev_ds=> select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1' limit 1;
                 uri                  |        date         
--------------------------------------+---------------------
 ******************************R_0007 | 2020-09-14 00:00:00
(1 row)

Time: 54.391 ms
dev_ds=> SET enable_seqscan = on;
SET
Time: 0.335 ms
dev_ds=> select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1' limit 1;
                 uri                  |        date         
--------------------------------------+---------------------
 ******************************R_0007 | 2020-09-14 00:00:00
(1 row)

Time: 1064404.383 ms (17:44.404)

Dernière modification par herve.lefebvre (04/02/2021 12:36:30)

Hors ligne

#22 04/02/2021 12:38:47

frost242
Administrateur

Re : Index GIN et égalité

Merci du retour; Le coup du ORDER BY pour forcer Postgres à utiliser l'index semble faire mouche. Vous pouvez valider le temps d'exécution avec EXPLAIN (ANALYZE, BUFFERS).


Thomas Reiss

Hors ligne

#23 04/02/2021 12:44:19

Re : Index GIN et égalité

frost242 a écrit :

Merci du retour; Le coup du ORDER BY pour forcer Postgres à utiliser l'index semble faire mouche. Vous pouvez valider le temps d'exécution avec EXPLAIN (ANALYZE, BUFFERS).

Oui ça le fait avec le order by :

dev_ds=> SET enable_seqscan = on;
SET
Time: 0.331 ms
dev_ds=> EXPLAIN (ANALYZE, BUFFERS) select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1' order by extra->>'id_cellar' limit 1;
                                                                      QUERY PLAN                                                                      
------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=189692.39..189692.39 rows=1 width=82) (actual time=64.791..64.792 rows=1 loops=1)
   Buffers: shared hit=9021
   ->  Sort  (cost=189692.39..189821.79 rows=51760 width=82) (actual time=59.176..59.176 rows=1 loops=1)
         Sort Key: ((extra ->> 'id_cellar'::text))
         Sort Method: top-N heapsort  Memory: 25kB
         Buffers: shared hit=9021
         ->  Bitmap Heap Scan on document  (cost=3645.60..189433.59 rows=51760 width=82) (actual time=59.160..59.166 rows=4 loops=1)
               Recheck Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
               Heap Blocks: exact=4
               Buffers: shared hit=9021
               ->  Bitmap Index Scan on ix_ds_document_id_cellar  (cost=0.00..3632.66 rows=51760 width=0) (actual time=59.142..59.143 rows=4 loops=1)
                     Index Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
                     Buffers: shared hit=9017
 Planning Time: 0.143 ms
 JIT:
   Functions: 5
   Options: Inlining false, Optimization false, Expressions true, Deforming true
   Timing: Generation 0.803 ms, Inlining 0.000 ms, Optimization 0.385 ms, Emission 5.037 ms, Total 6.225 ms
 Execution Time: 65.648 ms
(19 rows)

Time: 66.068 ms
dev_ds=> 

Hors ligne

#24 04/02/2021 13:02:36

frost242
Administrateur

Re : Index GIN et égalité

Merci. J'ai fait une bourde pour la CTE, il faut utiliser AS MATERIALIZED et non AS NOT MATERIALIZED. A vous de voir si c'est meilleur, mais à mon avis le ORDER BY supplémentaire sera meilleur.


Thomas Reiss

Hors ligne

#25 04/02/2021 13:08:53

Re : Index GIN et égalité

frost242 a écrit :

Merci. J'ai fait une bourde pour la CTE, il faut utiliser AS MATERIALIZED et non AS NOT MATERIALIZED. A vous de voir si c'est meilleur, mais à mon avis le ORDER BY supplémentaire sera meilleur.

Oui effectivement, ça le fait aussi :

dev_ds=> explain WITH w AS MATERIALIZED (
select uri, date from ds.document where extra->>'id_cellar' like '487d4f99-f65b-11ea-991b-01aa75ed71a1'
)
SELECT * FROM w LIMIT 1;
                                                 QUERY PLAN                                                  
-------------------------------------------------------------------------------------------------------------
 Limit  (cost=189304.19..189304.21 rows=1 width=40)
   CTE w
     ->  Bitmap Heap Scan on document  (cost=3645.60..189304.19 rows=51760 width=50)
           Recheck Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
           ->  Bitmap Index Scan on ix_ds_document_id_cellar  (cost=0.00..3632.66 rows=51760 width=0)
                 Index Cond: ((extra ->> 'id_cellar'::text) ~~ '487d4f99-f65b-11ea-991b-01aa75ed71a1'::text)
   ->  CTE Scan on w  (cost=0.00..1035.20 rows=51760 width=40)
 JIT:
   Functions: 5
   Options: Inlining false, Optimization false, Expressions true, Deforming true
(10 rows)

Time: 36.457 ms

Mais bon, le problème n'était pas d'être à 10 ms près, mais à un quart d'heure près :-D

Hors ligne

Pied de page des forums