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

PostgreSQL :meilleur moyen de joindre de petits sous-ensembles de grandes tables

Comme vous l'avez mentionné, la seule façon de vraiment savoir est de comparer les plans d'exécution. En fait, la meilleure façon serait d'utiliser EXPLAIN ANALYZE , afin qu'il exécute réellement la requête et insère les résultats dans la sortie avec les estimations, afin que vous puissiez avoir une idée du planificateur de requête par rapport à la réalité.

Cependant, en général, ce que je ferais dans une situation comme celle-ci serait probablement de créer une table temporaire pour le sous-ensemble client, puis JOIN qu'aux orders table. Vous pouvez éventuellement utiliser WITH au lieu de tout faire en une seule requête.

Donc, quelque chose comme :

CREATE TEMP TABLE tmp_clients AS
SELECT c.clientid
FROM clients c
WHERE c.city = 'New York'
ORDER BY c.clientid;

SELECT *
FROM orders AS o
JOIN tmp_clients AS c ON (o.clientid = c.clientid)
ORDER BY o.clientid;

De cette façon, tmp_clients ne contient que les clients de New York -- ~5 000 lignes -- et c'est cette table qui sera jointe à la table des commandes.

Vous pouvez également, pour optimiser davantage, créer un index sur la table temporaire (sur le clientid) puis ANALYZE avant de faire le JOIN pour s'assurer que le JOIN est fait uniquement sur l'index. Vous voudriez vérifier les plans de requête dans chaque cas pour voir la différence relative (ou gardez simplement cela à l'esprit si le JOIN n'est pas aussi rapide que vous le souhaiteriez).

Réponse au commentaire de @poshest :

Cela ressemble aux tables temporaires s'empilent, ce qui augmenterait l'empreinte mémoire et, pour une connexion de longue durée, la fonctionnalité semble être une fuite de mémoire.

Dans ce cas, il ne s'agirait pas d'une véritable fuite, car les tables temporaires sont limités à une connexion. Ils disparaissent automatiquement, mais pas avant la fin de la connexion. Cependant, vous pouvez les faire disparaître immédiatement lorsque vous en avez terminé avec eux. Simplement DROP la table comme vous le feriez avec n'importe quelle autre une fois que vous en avez fini avec eux, et je suppose que vous pourrez appeler la fonction un tas de fois - sur la même connexion - sans le même type d'augmentation monotone de l'empreinte mémoire. /P>