Vous n'êtes pas identifié(e).
Bonjour,
J'utilise depuis peu postgres.
J'ai besoin de réaliser des requêtes sur ma base postgres à partir d'ACCESS et ce par le biais d'une connexion ODBC.
La table sur laquelle je réalise des requêtes contient 8 000 000 de lignes.
Dans la plupart des requêtes simples que j'exécute, j'obtiens un résultat quasi instantané, par exemple :
- agrégation de ma table sur un champ X...
- avec somme des enregistrements du champ Y...
- sélection d'un seul de mes individus du champ X
Malheureusement, dès que je souhaite réaliser une requête un peu plus "lourde" à savoir la même requête que précédemment mais sans sous-sélectionner un de mes individus la requête plante systématiquement.
Requête type :
- agrégation de ma table sur un champ X...
- avec somme des enregistrements du champ Y... BUG !!!
Message d'erreur renvoyé par ACCESS :
ODBC -- l'appel à échoué
Bindingd were not allocated properly. (#15)
Pour informations :
- quand la requête "simple" retourne une réponse quasi instantanée, la requête plus "lourde" demande 10 à 20 secondes.
- dans le cas de la requête plus "lourde" la charge mémoire du PC client grimpe en flèche.
Quelqu'un saurait-il d'où peu venir le problème ? Limitation du pilote ODBC, limitation côté serveur postgres (donc mauvaise configuration de ma part)...
D'avance merci,
Fabrice.
Hors ligne
Étonnant que vous ne parliez pas d'une limitation d'Access. Pour moi, le problème vient soit du driver ODBC soit d'Access.
Pour éliminer PostgreSQL de l'équation, il faudrait vérifier le contenu des logs de PostgreSQL pour voir si des messages apparaissent suite à l'exécution de la requête. D'autre part, il est aussi possible de récupérer la requête exécutée et de tenter son exécution via psql pour voir si ça passe (sans Access et ODBC).
Guillaume.
Hors ligne
En effet, ACCESS peut très bien être la cause du problème. J'ai aussi cherché dans cette direction et celle du pilote odbc mais je n'ai, pour l'instant, pas trouvé de réponses à mon problème de ce côté non plus. Je suis ouvert à toutes les pistes.
Comme je débute, voici ce que j'ai trouvé comme fichier log, en espérant que ce soit ce que vous évoquez :
2011-01-20 09:00:46 CET FATAL: le système de bases de données se lance
2011-01-20 09:00:46 CET LOG: le système de bases de données a été arrêté à 2011-01-19 18:11:11 CET
2011-01-20 09:00:47 CET FATAL: le système de bases de données se lance
2011-01-20 09:00:48 CET LOG: le système de bases de données est prêt pour accepter les connexions
2011-01-20 09:00:48 CET LOG: lancement du processus autovacuum
2011-01-20 09:20:53 CET ERREUR: la relation « msysconf » n'existe pas au caractère 28
2011-01-20 09:20:53 CET INSTRUCTION : SELECT Config, nValue FROM MSysConf
2011-01-20 09:26:55 CET LOG: n'a pas pu envoyer les données au client : Unknown winsock error 10061
2011-01-20 09:26:55 CET INSTRUCTION : SELECT "commune" ,"DCLT" ,"IPONDI" FROM "public"."fd_mobpro_2006"
2011-01-20 09:27:04 CET LOG: n'a pas pu recevoir les données du client : Unknown winsock error 10061
2011-01-20 09:27:04 CET LOG: fin de fichier (EOF) inattendue de la connexion du client
2011-01-20 09:27:06 CET ERREUR: la relation « msysconf » n'existe pas au caractère 28
2011-01-20 09:27:06 CET INSTRUCTION : SELECT Config, nValue FROM MSysConf
2011-01-20 09:28:18 CET LOG: n'a pas pu envoyer les données au client : Unknown winsock error 10061
2011-01-20 09:28:18 CET INSTRUCTION : SELECT "commune" ,"DCLT" ,"IPONDI" FROM "public"."fd_mobpro_2006"
2011-01-20 09:28:29 CET LOG: n'a pas pu recevoir les données du client : Unknown winsock error 10061
2011-01-20 09:28:29 CET LOG: fin de fichier (EOF) inattendue de la connexion du client
2011-01-20 09:28:29 CET ERREUR: la relation « msysconf » n'existe pas au caractère 28
2011-01-20 09:28:29 CET INSTRUCTION : SELECT Config, nValue FROM MSysConf
Pour ce qui est de récupérer la requête exécutée depuis le pilote... je ne sais pas faire. Quelle en est la méthode ?
Merci
Hors ligne
Pas depuis le pilote mais depuis PostgreSQL. En tout cas, il y a déjà des erreurs avec des requêtes qui font appel à une table msysconf qui n'existe pas. Ça ne vient clairement pas du pilote ODBC. Donc soit d'access, soit d'autre chose.
Pour avoir la requête, le plus simple est de configurer PostgreSQL pour tout tracer. Par exemple avec un log_min_duration_statement à 0. J'ai regardé sur Google, il y a quelqu'un lien concernant votre message d'erreur. Ça ne m'a pas dit grand-chose. Malgré cela, vous feriez bien de faire la même recherche (Binding were not allocated properly access postgres), comme vous connaissez Access plus que moi, ça devrait vous en dire plus.
Guillaume.
Hors ligne
Merci pour toutes ces infos.
De mon côté j'ai bien avancé sur le fait que le problème puisse venir d'ACCESS, et notamment à la lecture du log qui laisse entendre que postgres "n'a pas pu recevoir les données du client".
Pour réaliser ma requête je faisais, entre autres, une jointure entre une table sous ACCESS et une autre dans postgres... ce qui est très certainement une erreur de débutant. Résultat j'ai importé ladite table directement dans postgres et recommencé ma requête depuis ACCESS... et ça fonctionne !!!
Le temps de réponse est cependant très long, de l'ordre de 5 à 10 minutes, ce qui m'étonne un peu pour un SGBD aussi performant postgres. Ça me laisse entendre qu'il y a certainement encore des choses que je ne fais pas correctement.
Mes deux tables ont une clé primaire et son indexées sur les champs principaux que j'utilise pour requêter, en l'occurrence les codes insee de mes communes.
N'est-il pas nécessaire de faire d'autres choses pour que les performance soient meilleurs ?
Merci
Hors ligne
Impossible à dire sans connaître la requête et le plan d'exécution de celle-ci.
Guillaume.
Hors ligne
Voici la requête telle que saisie sous ACCESS :
SELECT
public_communes_fr_rgpt.Code_AU,
public_communes_fr_rgpt_1.Code_AU,
Sum(public_fd_mobpro_2006.IPONDI)
FROM
public_communes_fr_rgpt AS public_communes_fr_rgpt_1 INNER JOIN (public_communes_fr_rgpt INNER JOIN public_fd_mobpro_2006 ON public_communes_fr_rgpt.code_insee = public_fd_mobpro_2006.commune) ON public_communes_fr_rgpt_1.code_insee = public_fd_mobpro_2006.DCLT
WHERE
(((public_communes_fr_rgpt.Code_AU)<>"999" And (public_communes_fr_rgpt.Code_AU)<>"000") AND ((public_communes_fr_rgpt_1.Code_AU)<>"999" And (public_communes_fr_rgpt_1.Code_AU)<>"000"))
GROUP BY
public_communes_fr_rgpt.Code_AU, public_communes_fr_rgpt_1.Code_AU;
Hors ligne
Bonjour,
je trouve cette requête curieuse, j'ai l'impression qu'il y a un produit cartésien entre public_communes_fr_rgpt et public_communes_fr_rgpt_1
à moins que ce soit la notation access qui m'induise en erreur.
Est ce que celle ci marcherai dans psql ?
SELECT
B.Code_AU, C.Code_AU,Sum(A.IPONDI)
FROM fd_mobpro_2006 A
INNER JOIN communes_fr_rgpt B ON B.code_insee = A.DCLT
INNER JOIN communes_fr_rgpt C ON B.code_insee = A.commune
WHERE B.Code_AU not in ('999','000')
AND C.Code_AU not in ('999','000')
GROUP BY B.Code_AU, C.Code_AU;
Cordialement
Hors ligne
Bonsoir,
Je viens d'essayer le code proposé mais ça ne fonctionne pas. Il est aussi fort probable que je fasse des erreurs. Je vais retenter tout de même.
Concernant la particularité de ma requête, c'est qu'elle concerne une table d'origine/destination :
Chaque ligne représente un déplacement d'une commune d'habitation (champ commune) vers une commune de travail (champ DCLT)
Comme je souhaite agréger mes communes à l'aide d'une seconde table contenant le code des aires urbaines auxquelles celles-ci appartiennent je joins donc ma table des aires urbaine :
- une première fois sur mon champ commune
- une seconde fois sur mon champ DCLT
...afin de demander une agrégation sur les aires urbaine d'origine et également sur les aires urbaine de destination.
L'objectif étant d'obtenir les flux de migration entre les aires urbaines (et non pas entre les communes).
En tous cas merci pour l'aide, je continue à tester vos propositions.
Cordialement
Hors ligne
Bonsoir,
Je viens d'essayer le code proposé mais ça ne fonctionne pas. Il est aussi fort probable que je fasse des erreurs. Je vais retenter tout de même.
Bonjour, peux tu préciser comment ça ne fonctionne pas ? message d'erreur ? ou autre ?
Si je suis ton raisonnement, tu veux connaitre pour chaque ligne de fd_mobpro_2006 la zone urbaine attaché au champ "DCLT"
et celle attaché au champ "commune".
La correspondance zone urbaine <-> code commune se trouve dans la table "communes_fr_rgpt"
Qu'est ce qu'IPONDI ?
Cordialement
Hors ligne
Bonjour,
Je réponds avec du retard, d'autres impératifs m'ont imposé une "pause" dans mes travaux sur postgres.
Tu as bien saisi l'objet de ma requête.
Une fois que j'ai rattaché une aire urbaine à chacune de mes communes je réalise ensuite une agrégation par aire urbaine.
Mon champ IPONDI se rapporte au poids de chacun de mes individus dans la population française (chacun de mes individus représentant un échantillon de la population, et également un déplacement domicile-travail), poids qu'il me faut sommer pour obtenir la nombre total de déplacements entre aires urbaines.
Voici se que sa donne :
Individu l Aire urbaine <-> Commune de domicile l Commune de travail <-> Aire urbaine l IPONDI
N°1 AU1 Commune A Commune Z AU2 1,5
N°2 AU1 Commune B Commune Y AU8 2
N°3 AU2 Commune Z Commune X AU3 3
N°4 AU1 Commune C Commune P AU2 2,5
N°5 AU2 Commune E Commune V AU3 4
Résultat de la requête :
Aire urbaine (domicile) l Aire urbaine (travail) l Somme de IPONDI
AU1 AU2 4
AU1 AU8 2
AU2 AU3 7
Le tout se réalisant sur une base à l'individu... chaque individu ayant un poids... et il y a 8 000 000 d'individus. Ça commence donc à faire des requêtes complexes et lourdes.
J'arrive donc à obtenir des réponses à mes requêtes en 2-3 minutes. Ce qui ne m'apparaît pas problématique pour l'usage que j'ai à en faire, à savoir extraire des données de ma table de départ pour les exploiter/analyser par la suite.
Hors ligne
Ok, par contre tu ne m'as pas dit en quoi le code que je t'avais fournit ne focntionnait pas ?
Y'a t-il un message d'erreur (si tu l'as exécuté dans psql, il devrait y avoir quelque chose)
Cordialement
Hors ligne
Bonsoir,
Ça y est je suis parvenu à utiliser le code que tu m'avais transmis.
Le problème venait bien de moi et de mon peu d'expérience avec postgres. J'avais notamment des noms de champs avec des majuscules. Une fois corrigé la requête s'exécute parfaitement.
Ton code m'a même permis de rajouter d'autres conditions de sous sélection et de tri.
SELECT
communes_fr_rgpt.code_au,
communes_fr_rgpt2.code_au,
Sum(fd_mobpro_2006.ipondi)
FROM
fd_mobpro_2006
INNER JOIN communes_fr_rgpt ON communes_fr_rgpt.code_insee = fd_mobpro_2006.commune
INNER JOIN communes_fr_rgpt2 ON communes_fr_rgpt2.code_insee = fd_mobpro_2006.dclt
WHERE communes_fr_rgpt2.code_au not in ('999','000')
AND communes_fr_rgpt.code_au not in ('999','000')
AND communes_fr_rgpt.code_au <> communes_fr_rgpt2.code_au
GROUP BY communes_fr_rgpt2.code_au, communes_fr_rgpt.code_au
ORDER BY communes_fr_rgpt.code_au;.
Merci beaucoup pour ton aide Meles
Hors ligne
My pleasure !
Hors ligne