Dans Postgres, vous pouvez spécifier une clause IN, comme ceci:
SELECT * FROM user WHERE id IN (1000, 1001, 1002)
Quelqu'un sait-il quel est le nombre maximum de paramètres que vous pouvez transmettre à IN?
postgresql
Alex Riley
la source
la source
PLAN DE DEMANDE
Mais si essayez la 2ème requête:
PLAN DE DEMANDE
Nous pouvons voir que postgres construit une table temporaire et la rejoindre
la source
Il n'y a pas de limite au nombre d'éléments que vous passez à la clause IN. S'il y a plus d'éléments, il le considérera comme un tableau, puis pour chaque analyse dans la base de données, il vérifiera s'il est contenu dans le tableau ou non. Cette approche n'est pas si évolutive. Au lieu d'utiliser la clause IN, essayez d'utiliser INNER JOIN avec une table temporaire. Référez-vous à http://www.xaprb.com/blog/2006/06/28/why-large-in-clauses-are-problematic/ pour plus d'informations. L'utilisation des échelles INNER JOIN ainsi que de l'optimiseur de requêtes peut utiliser la jointure par hachage et d'autres optimisations. Alors qu'avec la clause IN, l'optimiseur n'a aucun moyen d'optimiser la requête. J'ai remarqué une accélération d'au moins 2x avec ce changement.
la source
OR
et deIN
clauses en raison de la surcharge importante liée à l'analyse et à la planification de telles requêtes, je n'ai pas pu confirmer le problème avec Postgres 9.5, voir cette réponse .En tant que personne plus expérimentée avec Oracle DB, j'étais également préoccupée par cette limite. J'ai effectué un test de performance pour une requête avec ~ 10'000 paramètres dans une
IN
-list, récupérant des nombres premiers jusqu'à 100'000 à partir d'une table avec les 100'000 premiers entiers en listant tous les nombres premiers comme paramètres de requête .Mes résultats indiquent que vous n'avez pas à vous soucier de surcharger l'optimiseur de plan de requête ou d'obtenir des plans sans utilisation d'index , car cela transformera la requête pour l'utiliser
= ANY({...}::integer[])
là où elle peut exploiter les indices comme prévu:Cependant, ce fil (assez ancien) sur la liste de diffusion pgsql-hackers indique qu'il y a toujours un coût non négligeable dans la planification de telles requêtes, alors croyez-moi sur parole.
la source
Si vous avez une requête comme:
vous pouvez augmenter les performances si vous réécrivez votre requête comme:
la source
EXPLAIN
dit qu'il réécrit en interne monIN (...)
asANY ('{...}'::integer[])
.J'ai juste essayé. la réponse est -> entier hors plage sous la forme d'une valeur sur 2 octets: 32768
la source
Vous pouvez envisager de refactoriser cette requête au lieu d'ajouter une liste d'ID arbitrairement longue ... Vous pouvez utiliser une plage si les ID suivent effectivement le modèle de votre exemple:
Une autre option consiste à ajouter une sélection interne:
la source