OVH Cloud OVH Cloud

SQLobject et consommation mémoire

4 réponses
Avatar
sir_highleaf
Bonjour,

Je teste actuellement SQLobject pour acc=E9der =E0 mes donn=E9es (MySQL).

Je fais mes tests d'=E9criture avec un nombre d'enregistrements
cons=E9quent (1 700 000).

C'est une simple table avec deux champs.

Quand j'utilise SQLobject, j'ai une consommation de m=E9moire
horriblement importante au point de prendre toute la m=E9moire de l'OS.
Je cherche et je m'aper=E7ois en fait, qu'un objet se cr=E9e =E0 chaque
enregistrement, augmentant ainsi la consommation m=E9moire jusqu'=E0
saturation. Je cherche un peu et je vois une option "cache" pour la
connexion. Cette option am=E9liore un peu la consommation m=E9moire mais
le r=E9sultat est toujours une saturation m=E9moire.

Voci le code basique :

from sqlobject import *

sqlhub.processConnection =3D
connectionForURI('mysql://georges:abidbol@localhost/dictionnaire?cache=3D')

class Divers(SQLObject):
mot =3D StringCol()

for ligne in open('liste.txt') :
Divers(mot=3Dligne) # Ecriture dans la base

Bref, je finis par tester avec MySQLdb et j'arrive =E0 terminer
l'=E9criture des 1 700 000 enregistrements en 8 minutes environ avec une
consommation m=E9moire faible (pour info une requete SELECT ALL sur les
1 700 000 enregistrements se fait en 23 secondes).

Ma question est donc de savoir si on peut lib=E9rer cette m=E9moire au
fur et =E0 mesure en utilisant SQLobject comme le fait MySQLdb =E0 chaque
enregistrement ? J'ai peut-=EAtre oubli=E9 quelque chose ou il existe une
subtilit=E9 qui m'=E9chappe...

Cordialement,

Julien

4 réponses

Avatar
Olivier
Hello,


Quand j'utilise SQLobject, j'ai une consommation de mémoire
horriblement importante au point de prendre toute la mémoire de l'OS.


Je ne connais pas grand-chose à MySQL et SQLobject, mais ce ne serait
pas une histoire de commit ?

Olivier

Avatar
Laurent Pointal
sir_highleaf wrote:
Bonjour,

Je teste actuellement SQLobject pour accéder à mes données (MySQL).

Je fais mes tests d'écriture avec un nombre d'enregistrements
conséquent (1 700 000).

C'est une simple table avec deux champs.

Quand j'utilise SQLobject, j'ai une consommation de mémoire
horriblement importante au point de prendre toute la mémoire de l'OS.
Je cherche et je m'aperçois en fait, qu'un objet se crée à chaque
enregistrement, augmentant ainsi la consommation mémoire jusqu'à
saturation. Je cherche un peu et je vois une option "cache" pour la
connexion. Cette option améliore un peu la consommation mémoire mais
le résultat est toujours une saturation mémoire.


Hummm... Cherche plutôt une option de cache vraiment liée aux objets -
voir s'il utilise les weakref qq part, s'il est possible de purger son
cache d'objets.


[HS et ça ne fera pas avancer ton problème]

J'aime pô ces outils - je recopie ici une critique que j'ai émis sur un
outil similaire utilisé en Java (posté dans la liste pythonfr il y a une
petite année) - j'avais eu un problème similaire au tien: l'outil
d'abstraction me chargeait toute la base de données:



Pas en Python, mais en Java, j'ai eu à reprendre un code qui utilisait
Hibernate.

Très bien dans le principe. Potentiellement sûrement très bien quand on
sait l'utiliser. Mais très dangereux si on ne comprends pas ce qui se
passe derrière.

La personne qui avait fait le code avant:
-chargeait des objets sans utiliser les liens 'lazy' (résolus uniquement
lorsque l'on active les références vers les objets).
-relachait la session avec le sgbd quasiment après chaque requête.

Résultat, dans certaines opérations je me retrouvais à charger quasiment
l'intégralité de la base de données (éventuellement plusieurs fois)...
pas de problème pour le codeur initial car les données étaient
relativement peu volumineuses, juste des ralentissements un peu bizarres
lors de l'ouverture de certains dialogues. Quand je suis passé à des
tests plus volumineux, aye.
J'ai résolu en utilisant une connexion permanente à la base de données.
C'est pas optimal (toutes les données sont en mémoires), mais c'est
devenu utilisable.


Ce que je n'aime pas:
Un serveur de bases de données relationnelles est fait pour traiter des
requêtes pouvant éventuellement manipuler de gros volumes de données,
les mettre à jour, etc... tout cela étant fait sur le serveur.
Lorsque l'on passe par une couche d'abstraction d'objets automatiques,
on transfert toutes les données et les traitements vers le client, le
serveur n'étant quasiment plus qu'un moyen de stockage.
Et là c'est débile. J'ai vu un exemple d'utilisation d'Hibernate, ou
pour ajouter 10% sur les prix d'articles dans une base de données, ils
faisaient une joli itération sur une liste d'objets générés par
hibernate, mettant à jour un champs dans chaque objet. A quoi sert alors
le fait d'avoir un moteur de bases de données capable de modifier les
données avec des expressions SQL ?


Mon avis: bien utilisé ça peut être pratique et puissant. Mais pour bien
l'utiliser il faut savoir ce qu'est un SGBDR (avoir joué un peu avec SQL
et les requêtes), comprendre un minimum comment fonctionne la couche
intermédiaire, et savoir/pouvoir limiter l'utilisation du côté objet
lorsque les choses sont plus efficaces du côté SGBDR. Mais là IMHO on
casse une partie de l'intérêt de ces outils car on mélange alors du haut
et du bas niveau et on oblige le développeur à connaître un mapping que
certains voudraient garder transparent (voir opaque afin de pouvoir le
modifier la réalisation côté SGBDR).

A utiliser en connaissance de cause.

[/HS]


A+, bonne recherche.

Laurent.

Avatar
William Dode
On 07-12-2005, Laurent Pointal wrote:
sir_highleaf wrote:
Bonjour,

Je teste actuellement SQLobject pour accéder à mes données (MySQL).

Je fais mes tests d'écriture avec un nombre d'enregistrements
conséquent (1 700 000).

C'est une simple table avec deux champs.

Quand j'utilise SQLobject, j'ai une consommation de mémoire
horriblement importante au point de prendre toute la mémoire de l'OS.
Je cherche et je m'aperçois en fait, qu'un objet se crée à chaque
enregistrement, augmentant ainsi la consommation mémoire jusqu'à
saturation. Je cherche un peu et je vois une option "cache" pour la
connexion. Cette option améliore un peu la consommation mémoire mais
le résultat est toujours une saturation mémoire.


Hummm... Cherche plutôt une option de cache vraiment liée aux objets -
voir s'il utilise les weakref qq part, s'il est possible de purger son
cache d'objets.


[HS et ça ne fera pas avancer ton problème]

J'aime pô ces outils


Juste pour dire que moi non plus, car j'en ais fait un dans le même
genre que sqlobject, encore plus sofistiqué puisqu'il permétait de
générer aussi bien des formulaires web que des formulaires wxwindows et
des états reportlab !
Et bien malgrès tout je l'ais abandonné car on se retrouve à avoir
besoin d'une douzaine d'objets énormes pour une simple requête sql et
tout petit changement dans l'usine à gaz en question entraine des
effets de bords sur 15 projets...

Pour l'exemple en question (insertion de 1700000 enregistrement) il est
d'autant plus clair que ce n'est pas du tout l'outil idéal...

--
William Dodé - http://flibuste.net


Avatar
sir_highleaf
Bonjour,

Disons qu'après de nombreux de tests, je n'ai toujours pas trouvé le
moyen de remédier à ce problème et j'avoue que je partage désormais
votre point de vue. On ajoute une couche pour se faciliter la vie, pas
pour se la compliquer. Je vais rester avec MySQLdb.

Merci.

Julien