Mysql
 sql >> Base de données >  >> RDS >> Mysql

Vitesse du mot-clé IN dans MySQL/PostgreSQL

Dans PostgreSQL, exactement ce que vous obtiendrez ici dépend de la table sous-jacente, vous devez donc utiliser EXPLAIN ANALYZE sur certains exemples de requêtes sur un sous-ensemble utile de vos données pour déterminer exactement ce que l'optimiseur va faire (assurez-vous que les tables que vous courent contre ont également été ANALYSÉS). IN peut être traité de différentes manières, et c'est pourquoi vous devez examiner quelques exemples pour déterminer quelle alternative est utilisée pour vos données. Il n'y a pas de réponse générique simple à votre question.

En ce qui concerne la question spécifique que vous avez ajoutée dans votre révision, par rapport à un ensemble de données trivial sans index impliqué, voici un exemple des deux plans de requête que vous obtiendrez :

postgres=# explain analyze select * from x where s in ('123','456');
 Seq Scan on x  (cost=0.00..84994.69 rows=263271 width=181) (actual time=0.015..1819.702 rows=247823 loops=1)
   Filter: (s = ANY ('{123,456}'::bpchar[]))
 Total runtime: 1931.370 ms

postgres=# explain analyze select * from x where s='123' or s='456';
 Seq Scan on x  (cost=0.00..90163.62 rows=263271 width=181) (actual time=0.014..1835.944 rows=247823 loops=1)
   Filter: ((s = '123'::bpchar) OR (s = '456'::bpchar))
 Total runtime: 1949.478 ms

Ces deux temps d'exécution sont essentiellement identiques, car le temps de traitement réel est dominé par le balayage séquentiel sur la table ; exécuter plusieurs fois montre que la différence entre les deux est inférieure à la marge d'erreur d'exécution à exécution. Comme vous pouvez le voir, PostgreSQL transforme le cas IN en utilisant son filtre ANY, qui devrait toujours s'exécuter plus rapidement qu'une série de OU. Encore une fois, ce cas trivial n'est pas nécessairement représentatif de ce que vous verrez sur une requête sérieuse impliquant des index et autres. Quoi qu'il en soit, le remplacement manuel des IN par une série d'instructions OR ne devrait jamais être plus rapide, car l'optimiseur sait ce qu'il y a de mieux à faire ici s'il dispose de bonnes données avec lesquelles travailler.

En général, PostgreSQL connaît plus d'astuces pour optimiser les requêtes compliquées que l'optimiseur MySQL, mais il dépend également fortement du fait que vous avez donné à l'optimiseur suffisamment de données pour travailler avec. Les premiers liens de la section "Optimisation des performances" du wiki PostgreSQL couvrent les éléments les plus importants nécessaires pour obtenir de bons résultats de l'optimiseur.