簡體   English   中英

導入CSV所需的時間太長

[英]Importing CSV takes too long

問題

我正在編寫一個應用程序引擎Karaoke Catalogs應用程序。 該應用程序非常簡單:在第一個版本中,它提供了將CSV歌曲列表導入目錄並顯示它們的功能。

我在CSV導入方面遇到問題:在我的開發環境中,導入17500條記錄需要花費很長時間(14小時)。 在生產環境中,它導入約1000條記錄,然后崩潰,並顯示代碼500。我正在瀏覽日志,但沒有找到任何有用的線索。

編碼

class Song(ndb.Model):
    sid     = ndb.IntegerProperty()
    title   = ndb.StringProperty()
    singer  = ndb.StringProperty()
    preview = ndb.StringProperty()

    @classmethod
    def new_from_csv_row(cls, row, parent_key):
        song = Song(
                sid=int(row['sid']),
                title=row['title'],
                singer=row['singer'],
                preview=row['preview'],
                key=ndb.Key(Song, row['sid'], parent=parent_key))
        return song

class CsvUpload(webapp2.RequestHandler):
    def get(self):
        # code omit for brevity 

    def post(self):
        catalog = get_catalog(…) # retrieve old catalog or create new

        # upfile is the contents of the uploaded file, not the filename
        # because the form uses enctype="multipart/form-data"
        upfile = self.request.get('upfile')

        # Create the songs
        csv_reader = csv.DictReader(StringIO(upfile))
        for row in csv_reader:
            song = Song.new_from_csv_row(row, catalog.key)
            song.put()

        self.redirect('/upload')

樣本數據

sid,title,singer,preview
19459,Zoom,Commodores,
19460,Zoot Suit Riot,Cherry Poppin Daddy,
19247,You Are Not Alone,Michael Jackson,Another day has gone. I'm still all alone

筆記

  • 在開發環境中,我嘗試導入多達17,500條記錄,並且沒有崩潰
  • 最初,記錄的創建和插入很快,但是隨着數據庫的發展,成千上萬的記錄創建和插入記錄所花費的時間增加到每條記錄幾秒鍾。

如何加快導入操作? 任何建議,提示或技巧將不勝感激。

更新資料

我聽從了Murph的建議,並使用KeyProperty將歌曲鏈接回目錄。 結果是大約4分20秒,可記錄17,500條記錄-有了巨大的進步。 這意味着,我還沒有完全理解NDB在App Engine中的工作方式,並且還有很長的路要走。

雖然有很大的進步,但公認的4分鍾以上仍然太長。 我現在正在研究Tim's和Dave的建議,進一步縮短了我的應用程序的感知響應時間。

在Google App Engine的數據存儲區中,對實體組的寫入限制為每秒1次寫入。

由於您為每首樂曲都指定了一個“父”鍵,因此它們都以一個實體組結尾,這很慢。

僅僅使用KeyProperty來跟蹤這種關系是否可以接受? 盡管數據可能存在更多的一致性問題,但這將更快。

除了其他答案:實體組,如果導入過程將花費超過60秒的時間,請使用任務,那么您的運行時間為10分鍾。

將csv作為BlobProperty存儲在實體中(如果壓縮后<1MB)或GCS,則存儲更大的文件,然后啟動任務,該任務從存儲中檢索CSV,然后進行處理。

首先,蒂姆走在正確的軌道上。 如果您無法在60秒內完成工作,請執行任務。 但是,如果您無法在10分鍾內完成工作,請改用App Engine MapReduce ,它可以將處理csv的工作分配給多個任務。 請參閱演示程序 ,其中包含您需要的一些片段。

為了降低開發時間,啟動dev_appserver時是否使用--use_sqlite選項?

Murph談到了問題的另一部分。 使用實體組,您可以限制插入次數(每個實體組)。 試圖使用單親父母插入17,500行根本無法正常工作。 這大約需要5個小時。

那么,您真的需要一致的讀取嗎? 如果這是一次上載,則可以進行非祖先插入(以目錄作為屬性),然后稍等一下數據最終變得一致嗎? 這簡化了查詢。

如果確實需要絕對一致的讀取,則可能需要將寫入拆分成多個父鍵。 這將增加您的寫入率,但以使祖先查詢更復雜為代價。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM