2017-09-29 7 views
0

J'ai une table dans Postgres avec une colonne JSONB, chaque ligne de la table contient un grand objet JSONB (~ 4500 clés, la chaîne JSON est d'environ 110 Ko dans un fichier txt). Je veux interroger ces lignes et obtenir l'objet JSONB entier.Retour de JSON de Postgres est lent

La requête est rapide - quand je lance EXPLAIN ANALYZE, ou omettez la colonne JSONB, elle revient en 100-300 ms. Mais quand j'exécute la requête complète, cela prend de l'ordre de minutes. La même requête sur une version précédente des données était également rapide (chaque JSONB était environ deux fois plus petit).

Quelques notes:

  • Cela finit en Python (via SQLAlchemy/psycopg2). Je suis inquiet que l'exécuteur de requête convertisse JSONB en JSON, alors il est codé en texte pour le transfert sur le fil, puis obtient le codage JSON à nouveau à la fin de Python. Est-ce correct? Si oui, comment pourrais-je atténuer ce problème? Lorsque je sélectionne la colonne JSONB en tant que ::text, la requête est à peu près deux fois plus rapide. Je n'ai besoin que d'un petit sous-ensemble du JSON (environ 300 touches ou 6% de touches). J'ai essayé des méthodes de filtrage de la sortie JSON dans la requête, mais elles ont provoqué une baisse importante des performances - il s'est avéré plus rapide de renvoyer l'objet entier.

+0

Essayez d'abord de créer et d'exécuter la requête en SQL pur, et exécutez-la sur le même nœud que le serveur postgres (si possible), cela éliminera tous les problèmes de sqlalchemy/réseau. Ensuite, fournissez plus de détails sur les données et le sql réel que vous avez exécuté. et les temps de requête. –

+0

@JonScott quand vous dites réécrire la requête en SQL pur, est-ce que cela signifie que je devrais essentiellement supprimer toutes les fonctionnalités spécifiques à PostgreSQL (comme JSON)? – glifchits

Répondre

0

Ce n'est pas nécessairement une solution, mais est ici une mise à jour:

En jetant la colonne JSON à text dans la requête Postgres, j'ai pu exécution de la requête en forte baisse couper et les résultats aller chercher sur la Fin de Python.

À l'extrémité de Python, en faisant json.loads pour chaque ligne dans le jeu de résultats m'amène à la synchronisation exacte en utilisant la requête régulière. Cependant, avec la bibliothèque ujson j'ai été en mesure d'obtenir une accélération significative. Les performances de la conversion en texte dans la requête, puis en appelant ujson.loads à la fin de python est environ 3 fois plus rapide que de simplement renvoyer JSON dans la requête.