Le mois dernier, j'ai eu un petit problème avec une requête de base de données assez basique. Il s'agit de 2 db.Models dont l'un se réfère à l'autre avec une propriété db.ReferenceProperty.Performances du datastore, mon code ou la latence du datastore
Le problème est que, selon les journaux d'administration, la requête prend environ 2 à 4 secondes. Je le dépouille à une forme nue et une liste pour afficher les résultats. Le put fonctionne très bien, mais le get accumule (à mon avis) beaucoup de temps CPU.
#The get look like this:
outputData['items'] = {}
labelsData = Label.all()
for label in labelsData:
labelItem = label.item.name
if labelItem not in outputData['items']:
outputData['items'][labelItem] = { 'item' : labelItem, 'labels' : [] }
outputData['items'][labelItem]['labels'].append(label.text)
path = os.path.join(os.path.dirname(__file__), 'index.html')
self.response.out.write(template.render(path, outputData))
#And the models:
class Item(db.Model):
name = db.StringProperty()
class Label(db.Model):
text = db.StringProperty()
lang = db.StringProperty()
item = db.ReferenceProperty(Item)
J'ai essayé de faire un certain nombre de façon différente ie. au lieu de ReferenceProperty qui stocke toutes les clés Label dans le modèle d'élément en tant que db.ListProperty.
Mes données de test sont juste 10 lignes dans Item et 40 dans Label. Donc mes questions: Est-ce une course de fous pour essayer d'optimiser ceci puisque l'utilisation élevée de cpu est due aux problèmes avec la banque de données ou ai-je juste foiré quelque part dans le code? ..fredrik
EDIT:
J'eu une très bonne réponse de djidjadji à la liste de diffusion AppEngine google.
Le nouveau code ressemble à ceci:
J'ai utilisé Appstats. Et c'est le ReferenceProperty qui fait et interroge pour chaque boucle qui est le problème. Mais j'ai reçu de l'aide sur la liste de diffusion googleappengine. Je ne savais pas comment faire le même résultat sans faire référence à ReferenceProperty. La solution consistait à utiliser get_value_for_datastore avant la boucle for. – fredrik
Vous avez toujours le problème d'itération sur une requête. Appeler .fetch() au lieu d'itérer sur la requête sera beaucoup plus efficace. En outre, voir ce billet de blog pour une recette pour résoudre les propriétés de référence: http://blog.notdot.net/2010/01/ReferenceProperty-prefetching-in-App-Engine –