114 votes

Différence entre LIKE et ~ dans Postgres

On m'a dit de "ne pas m'embêter avec". LIKE " et utiliser ~ à la place. Quel est le problème avec LIKE et comment ~ différent ?

Fait ~ a un nom dans ce contexte ou les gens disent-ils "u

6voto

Alex Points 439

J'ai juste fait un benchmark simple et rapide pour voir la différence de performance entre les deux opérateurs. quand aucun index n'est impliqué :

postgres=# \timing
Timing is on.
postgres=# SELECT count(1) FROM (SELECT val from generate_series(1, 10000000) x(val) WHERE val::text LIKE '%5%') AS x;
  count

 5217031
(1 row)

Time: 5631.662 ms
postgres=# SELECT count(1) FROM (SELECT val from generate_series(1, 10000000) x(val) WHERE val::text ~ '5') AS x;
  count

 5217031
(1 row)

Time: 10612.406 ms

Dans cet exemple, le LIKE est presque deux fois plus rapide que l'opérateur ~ opérateur. Donc si la vitesse est essentielle, je pencherais pour LIKE mais attention à ne pas optimiser prématurément. ~ vous donne beaucoup plus de flexibilité.

Pour ceux d'entre vous qui sont intéressés, voici les éléments suivants EXPLAIN pour les requêtes ci-dessus :

postgres=# EXPLAIN ANALYZE SELECT count(1) FROM (SELECT val from generate_series(1, 10000000) x(val) WHERE val::text LIKE '%5%') AS x;
                                                              QUERY PLAN

 Aggregate  (cost=20.00..20.01 rows=1 width=0) (actual time=9967.748..9967.749 rows=1 loops=1)
   ->  Function Scan on generate_series x  (cost=0.00..17.50 rows=1000 width=0) (actual time=1732.084..7404.755 rows=5217031 loops=1)
         Filter: ((val)::text ~~ '%5%'::text)
         Rows Removed by Filter: 4782969
 Total runtime: 9997.587 ms
(5 rows)

postgres=# EXPLAIN ANALYZE SELECT count(1) FROM (SELECT val from generate_series(1, 10000000) x(val) WHERE val::text ~ '5') AS x;
                                                              QUERY PLAN

 Aggregate  (cost=20.00..20.01 rows=1 width=0) (actual time=15118.061..15118.061 rows=1 loops=1)
   ->  Function Scan on generate_series x  (cost=0.00..17.50 rows=1000 width=0) (actual time=1724.591..12516.996 rows=5217031 loops=1)
         Filter: ((val)::text ~ '5'::text)
         Rows Removed by Filter: 4782969
 Total runtime: 15147.950 ms
(5 rows)

3voto

Oui, il s'agit de POSIX regex. Une autre alternative est d'utiliser l'approche standard SQL des expressions régulières avec l'opérateur "SIMILAR TO", bien qu'il fournisse un ensemble plus limité de fonctionnalités, il pourrait être plus facile à comprendre. Je pense que c'est une bonne référence de dba exchange : https://dba.stackexchange.com/questions/10694/pattern-matching-with-like-similar-to-or-regular-expressions-in-postgresql

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X