
Envoyé par
SQLpro
Si quelqu'un à des idées pour améliorer les performances de PostgreSQL je suis preneur. Bien entendu pour le second test on peut utiliser le module unaccent, mais cela modifie la structure de la table et oblige de réécrire les requêtes…
Euh, oui. J'essaie au moins pour la première partie (sensibilité à la casse), j'essaierai peut-être pour les accents plus tard.
Comme je ne connais pas bien la syntaxe SQL Server, quand j'ai vu la requête
SELECT * FROM T_CASSE WHERE DATUM = 'méli-mélo';
, je me suis d'abord demandé où diable la conversion de casse avait bien pu passer. T'emballes pas, j'ai vite compris qu'elle était implicite du fait de l'utilisation de , c'est bien cela?
Dans les requêtes PostgreSQL, en effet tu dois faire un appel à LOWER ou ILIKE dans le WHERE parce que ce n'est pas implicitement déclaré au moment de créer la table.
Oui, mais l'index dans tout ça?
Comment veux-tu donc faire une recherche insensible à la casse dans un index qui est basé sur la chaîne initiale, donc sensible à la casse? La dernière fois tu m'as reproché de ne pas avoir regardé le résultat du EXPLAIN, cette fois c'est toi qui aurais dû le faire, tu te serais aperçu qu'aucune des 3 requêtes PostgreSQL ne peut utiliser l'index!
Pour qu'il le soit, l'index doit contenir les chaînes en minuscules, comme ceci:
CREATE INDEX X_CASSE ON T_CASSE (LOWER(DATUM));
Dans le cas de SQL Server, tu n'avais pas à le faire parce que comme la colonne était déclarée avec , il a compris tout seul que l'index devait lui aussi être insensible à la casse. Faute de cette déclaration dans PostgreSQL, il faut utiliser LOWER à chaque fois, y compris au moment de créer l'index.
Evidemment tu vas me dire qu'alors SQL Server est meilleur parce qu'on ne déclare l'insensibilité à la casse qu'une seule fois. Honnêtement, moi je préfèrerais un serveur SQL qui offre les deux possibilités (mais je suppose que SQL Server le fait?): parfois on se dit de prime abord qu'une colonne doit être insensible à la casse, mais longtemps après on change d'avis... mais c'est plus facile de recréer un index qu'une table! Autre avantage, rien n'empêche d'avoir à la fois un index sur DATUM et un autre sur LOWER(DATUM), des fois qu'on ait beaucoup de requêtes avec et sans sensibilité à la casse - avec une déclaration associée à la colonne, c'est un peu plus difficile.
Oh, et avant que j'oublie, tant qu'on se limite à la question de la casse, il faudrait aussi faire le test en remplaçant VARCHAR par CITEXT (note: c'est un module externe à charger au préalable), comme ça tout, y compris l'index, se voit déjà appliquer l'insensibilité à la casse.
Comme je n'ai pas exactement le même matériel que toi (et que je n'ai pas SQL Server), je t'invite donc à refaire le test et à voir si la différence est toujours aussi flagrante. J'attends avec intérêt (et sans aucun à priori) de lire le résultat.
Pour le second problème avec les accents, je suppose qu'il faudrait écrire quelque chose comme
CREATE INDEX X_CASSE ON T_CASSE (remove_fr_accents(DATUM));
là encore ça vaut le coup de tester. Quoique, en y réfléchissant, aucune chance d'égaler ta requête SQL Server parce que "COLLATE French_CI_AI" est probablement implémenté en C, donc ce n'est pas une fonction en SQL procédural qui pourra rivaliser. Pour comparer objectivement, il faut:
- soit implémenter la fonction remove_fr_accents dans SQL Server et comparer quand les deux serveurs l'utilisent
- Soit implémenter remove_fr_accents sous la forme d'un module externe dans PostgreSQL. Pour ce faire j'aurais tendance à faire un lien avec la librairie ICU, écrite en C et particulièrement optimisée pour la langue française (je ne serais pas surpris d’apprendre que COLLATE French_CI_AI soit implémenté avec cette librairie en réalité)
Partager