아주 기본적인 데이터 저장소 쿼리로 지난 달에 약간의 문제가있었습니다. 그것은 db.ReferenceProperty로 다른 하나를 참조하는 2 db.Models를 포함합니다.Datastore 성능, 코드 또는 데이터 저장소 대기 시간
문제는 관리자 로그에 따르면 요청을 완료하는 데 약 2 ~ 4 초가 걸리는 것입니다. 나는 그 결과를 표시하기 위해 벌거 벗은 양식과 목록을 벗겨 냈다. put은 정상적으로 작동하지만 많은 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)
저는 여러 가지 방법으로 만들려고했습니다. 즉. ItemProperty의 모든 Label 키를 db.ListProperty로 저장하는 대신 ReferenceProperty를 사용합니다.
내 테스트 데이터는 Item에서 10 행이고 Label에서 40 행입니다.
그래서 내 질문 : 높은 CPU 사용량이 데이터 저장소의 문제로 인한 것이거나 코드의 어딘가에서 망가 졌기 때문에 최적화를 시도하는 것은 어리석은 일입니까? ..fredrik
는 편집 :
나는 구글에서 appengine 메일 링리스트에서 djidjadji에서 좋은 반응을 얻었다.
새로운 코드는 다음과 같습니다 :이 확실히의 일
outputData['items'] = {}
labelsData = Label.all().fetch(1000)
labelItems = db.get([Label.item.get_value_for_datastore(label) for label in labelsData ])
for label,labelItem in zip(labelsData, labelItems):
name = labelItem.name
try:
outputData['items'][name]['labels'].append(label.text)
except KeyError:
outputData['items'][name] = { 'item' : name, 'labels' : [label.text] }
저는 Appstats를 사용했습니다. 그리고 그것은 문제가되는 각 루프를 만들고 쿼리하는 ReferenceProperty입니다. 하지만 googleappengine 메일 링리스트에서 큰 도움을 받았습니다. ReferenceProperty를 참조하지 않고 동일한 결과를 만드는 방법을 알지 못했습니다. 해결책은 for 루프 앞에 get_value_for_datastore를 사용하는 것입니다. – fredrik
여전히 반복적 인 쿼리 문제가 있습니다. 쿼리를 반복하는 대신 .fetch()를 호출하면 훨씬 효율적입니다. 또한 참조 속성을 해결하는 방법에 대한 블로그 게시물을 참조하십시오. http://blog.notdot.net/2010/01/ReferenceProperty-prefetching-in-App-Engine –