0

아주 기본적인 데이터 저장소 쿼리로 지난 달에 약간의 문제가있었습니다. 그것은 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] } 

답변

3

당신은 당신의 코드를 최적화 할 수 있습니다. 예를 들어, 쿼리를 반복하면서 쿼리를 가져 와서 결과를 반복하는 것보다 효율적이지 않습니다.

Appstats을 사용하여 앱을 프로필하고 Patterns of Doom 게시물 시리즈를 확인하시기 바랍니다.

+0

저는 Appstats를 사용했습니다. 그리고 그것은 문제가되는 각 루프를 만들고 쿼리하는 ReferenceProperty입니다. 하지만 googleappengine 메일 링리스트에서 큰 도움을 받았습니다. ReferenceProperty를 참조하지 않고 동일한 결과를 만드는 방법을 알지 못했습니다. 해결책은 for 루프 앞에 get_value_for_datastore를 사용하는 것입니다. – fredrik

+1

여전히 반복적 인 쿼리 문제가 있습니다. 쿼리를 반복하는 대신 .fetch()를 호출하면 훨씬 효율적입니다. 또한 참조 속성을 해결하는 방법에 대한 블로그 게시물을 참조하십시오. http://blog.notdot.net/2010/01/ReferenceProperty-prefetching-in-App-Engine –

0

그냥 시도하지 마세요. 그것은 추측입니다. 당신은 바로 일부 시간이 일 것입니다. 다른 사람들에게도 같은 이유로 추측을 요구하지 마십시오.

매번 제대로 작업하십시오.

코드를 여러 번 일시 중지하고 호출 스택을 살펴보십시오. 그러면 정확히 무슨 일이 일어날 지 알려줄 것입니다.

+0

불행히도 지식이 부족할 때 추측됩니다. 손에 문제가. 더 자세한 정보를 모르는 경우에는 "더 많은 쿼리를 실행합니다"라는 것이 더욱 어려워집니다. Google appengine 메일 링리스트에 대한 해결책은 내가 할 수 있는지 몰랐던 일이었습니다. 나는이 문서에 대해 읽었지만 그것이 무엇을했는지 이해하지 못했다. 그래서 추측해서는 안된다고 말하면 어떻게 할 것입니까? – fredrik

+0

@fredrik : 여기 제가 제안하는 바가 있습니다. pdb (http://docs.python.org/library/pdb.html)에서 프로그램을 실행하십시오. 실행 중 Ctrl-Break 또는 Ctrl-C를 누르십시오. 호출 스택을 보려면 "w (여기)"를 입력하십시오. 그것이하고있는 일과 그 이유를 이해하십시오. 여러 번 반복하십시오.코드에서 X % 시간이 소비되면 X % (+/-) 스택에 표시됩니다. 데이터 저장소에있는 경우에도 마찬가지입니다. 측정 값은 근사치이지만 활동은 확실하고 세부적입니다. 그것은 내가 짐작하지 않는 것입니다. –

관련 문제