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

#1 05/04/2012 12:35:57

palex
Membre

optimisation CAST

bonjour

je viens de voir dans un plan d'execution cela :

              Index Cond: ((discriminator)::text = 'MAVALEUR'::text)

dans ma table, discriminator est declaré comme character varying(31)

dans la requete j'ai  produit.discriminator='MAVALEUR'

je suppose que si postgres cast mon champs discriminator en text s'est que la fonction d'égalité appelé par postgres prend 2 types text en parametre IN? comment est ce que je peut retrouver cette fonction qui doit etre de ce style :

equals(chaine1 text, chaine2 text)

-je suppose que le cast de charater varying vers text descend mes perfs sur la requete car du coup l'index sur le champs discriminator est utilisé 0 fois en prod car l'index contient des charater varying donc forcement il ne peut pas l'utiliser pour la comparaison?
-est ce que je dois pas plutot mettre discriminator comme champs text plutot que character varying ce qui eviterai le cast?
-si oui alors quel est l'utilité de character varying si on prevoie de faire des operations dessus car il risque de toujours caster la colonne en text?

merci pour vos reponses

Hors ligne

#2 05/04/2012 12:40:38

palex
Membre

Re : optimisation CAST

je pense que la fonction qui est appelé est :

 \df texteq
                           List of functions
   Schema   |  Name  | Result data type | Argument data types |  Type  
------------+--------+------------------+---------------------+--------
 pg_catalog | texteq | boolean          | text, text          | normal

Hors ligne

#3 05/04/2012 13:01:26

gleu
Administrateur

Re : optimisation CAST

-je suppose que le cast de charater varying vers text descend mes perfs sur la requete car du coup l'index sur le champs discriminator est utilisé 0 fois en prod car l'index contient des charater varying donc forcement il ne peut pas l'utiliser pour la comparaison?

Non, la ligne que vous avez ici vous indique que l'index est utilisé et que la condition est utilisé pour filtrer l'index rapidement.

est ce que je dois pas plutot mettre discriminator comme champs text plutot que character varying ce qui eviterai le cast?

Non.

si oui alors quel est l'utilité de character varying si on prevoie de faire des operations dessus car il risque de toujours caster la colonne en text?

varchar ne sert qu'à limiter le nombre de caractères maximum dans la chaîne. Si cette limite n'a pas d'utilité pour vous, autant passer en varchar() (donc sans indication de taille) ou en text pour éviter la vérification de taille à chaque insertion ou modification du champ.

Un truc que je ne pgie pas dans ce que vous dites. Le "Index Cond" vient d'un EXPLAIN exécuté sur la prod ?


Guillaume.

Hors ligne

#4 05/04/2012 14:19:52

palex
Membre

Re : optimisation CAST

en fait je n'ai pas accès direct à la prod mais le dump de prod de la veille est repliqué et je travail sur ce dernier, la premiere fois l'explain ma remonté cela :

 Bitmap Heap Scan on produit produitpre0_  (cost=196.05..208.09 rows=3 width=97) (actual time=17.578..20.224 rows=253 loops=6)
                              Recheck Cond: ((produitpre0_.fk_tva = tva7_.id) AND (produitpre0_.groupeid = 12038))
                             Filter: ((produitpre0_.datemodification >= '2012-03-05 00:00:00'::timestamp without time zone) AND (produitpre0_.typeproduit =
5) AND ((produitpre0_.discriminator)::text = 'PRESSE'::text) AND (produitpre0_.datemodification <= ('now'::text)::date))

et null part je vois l'utilisation de mon index, j'ai donc demandé au dba de regarder si l'index était utilisé en prod et il est toujours à 0. En revanche si je passe le champs en text je vois direct l'utilisation de mon index

        ->  Bitmap Index Scan on idx_produit_discriminator  (cost=0.00..507.77 rows=22780 width=0) (actual time=832.498..832.498
rows=678824 loops=1)
                    Index Cond: (discriminator = 'PRESSE'::text)

Hors ligne

#5 05/04/2012 14:50:28

palex
Membre

Re : optimisation CAST

c'est d'ailleurs suite à une formation Dalibo ou l'ou nous a dis que les cast était très couteux ce qui parrait logique finalement que je me pose la question smile

Hors ligne

#6 05/04/2012 15:23:10

gleu
Administrateur

Re : optimisation CAST

Les CAST sont coûteux mais dans ce cas, ça ne devrait rien changer. D'autre part, le nœud Bitmap Heap Scan correspond à la lecture de la table suite à un Bitmap Index Scan, donc normal que vous ne voyez pas votre index sur le Bitmap Heap Scan.

Cela étant dit, si en changeant la colonne à text, l'index est utilisé, je trouve ça curieux mais au moins votre problème est réglé smile


Guillaume.

Hors ligne

#7 05/04/2012 15:28:58

palex
Membre

Re : optimisation CAST

oui en effet en changeant le type ca va reglé le souci je pense, je vais confirmer cela en realisant un test simple de recherche sur cette colonne avec le type varchar et une autre fois le meme test avec le type text et voir avec l'explain ce qui se passe.

merci

Hors ligne

#8 06/04/2012 10:28:20

Marc Cousin
Membre

Re : optimisation CAST

Et en fait le cast entre varchar et text ne coûte rien: c'est la différence entre un cast, qui passe par une fonction, et un cast «binary coercible», qui indique que les deux types ont la même représentation mémoire, et qu'il n'y a donc rien à faire.

Par exemple:


    Type source    |    Type cible     |      Fonction      | Implicite ?
-------------------+-------------------+--------------------+-------------
boolean           | character varying | text               | assigné
"char"            | character varying | text               | assigné
character         | character varying | text               | oui
character varying | "char"            | char               | assigné
character varying | character         | (binary coercible) | oui
character varying | character varying | varchar            | oui
character varying | name              | name               | oui
character varying | regclass          | regclass           | oui
character varying | text              | (binary coercible) | oui
character varying | xml               | xml                | non
cidr              | character varying | text               | assigné
inet              | character varying | text               | assigné
name              | character varying | varchar            | assigné
text              | character varying | (binary coercible) | oui
xml               | character varying | (binary coercible) | assigné

On voit que passer de booleen ou inet en varchar appelle une fonction (normal, ce n'est pas la même structure), alors que passer de text en varchar ou de varchar en text se fait directement.


Marc.

Hors ligne

Pied de page des forums