繁体   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