【问题标题】:Simple DB query on Google App Engine taking a lot of CPU timeGoogle App Engine 上的简单数据库查询占用大量 CPU 时间
【发布时间】:2009-12-12 04:46:27
【问题描述】:

我对 Google App Engine 和 Python 还很陌生,但我刚刚发布了我的第一个真实网站。但是现在我遇到了一条路径的问题,该路径使用的 CPU(和 API CPU)时间比其他路径多得多。我已将其缩小到导致问题的单个数据存储提取:Carvings.all().fetch(1000)

在 App Engine 仪表板下,它会为对该路径的每个请求非常可靠地报告“1040cpu_ms 846api_cpu_ms”。看来这可能是我的客户在使用该网站时所经历的一些反应迟钝的原因。

所以我无法弄清楚这个查询的成本是什么。下面是相关的数据模型:

class Carving(db.Model):
    title = db.StringProperty(required=True)
    reference_number = db.StringProperty()
    main_category = db.StringProperty()
    sub_category = db.StringProperty()
    image = db.ReferenceProperty(CarvingImage)
    description = db.TextProperty()
    price = db.FloatProperty()
    size = db.StringProperty()
    material = db.StringProperty()
    added_at = db.DateTimeProperty(auto_now_add=True)
    modified_at = db.DateTimeProperty(auto_now=True)

在应用程序的其他地方,当我从数据存储中提取此模型时,我会进行更多过滤,我想这就是它们不会造成任何问题的原因。但是这个模型的实体总数刚刚超过 90 个,我无法想象为什么这么贵。

【问题讨论】:

    标签: python google-app-engine cpu-usage google-cloud-datastore


    【解决方案1】:
    • Memcache,如果你还没有的话,特别是如果要一次又一次地提取相同的雕刻。如果你总共只有 90 个,我想它们很快就会全部进入缓存,然后你应该是金子。

    • 您需要雕刻的所有属性吗?例如,如果您只是显示雕刻列表,则可以有一个单独的实体,类似于 CarvingSummary,它只有几个属性。这意味着您的架构已非规范化,但有时这就是您为速度付出的代价。

    另外,我假设这不是用户总是会点击的第一页?如果是这种情况,可能是云启动了一个新实例。

    【讨论】:

    • Memcache 工作得非常出色。尽管如此,我仍然对只返回约 90 个项目的查询占用如此多的 CPU 时间感到惊讶。谢谢!
    • 我同意。我对 python 方面不是很熟悉,我想知道 ReferenceProperty。您确定您的 ReferenceProperty 中的图像没有以某种方式被拉入吗?
    【解决方案2】:

    有时,如果您执行索引查询,而不是查询模型中的“所有”元素,您会获得更好的性能。

    另外,考虑使用内存缓存。

    【讨论】:

    • MEMCACHE!梅卡切!梅卡切! Facebook 拥有 12,000 多台 memcached 服务器。
    • 我假设索引查询是指使用某些条件?如果是这样,那么我之前就这样做了,但简化了查询以希望排除可能性。但是当我删除索引时性能确实下降了。
    • 谁反对我? App Engine 针对索引查询进行了优化,“所有”查询虽然通常很快,但有时速度较慢。这是设计的一个怪癖。
    【解决方案3】:

    您真的需要 1000 个实体吗? CPU 时间随着检索结果的数量或多或少呈线性增加,因此如果您实际上并不需要所有结果,则可能会浪费大量时间来获取和解码它们。

    【讨论】:

    • 数据存储区总共只有 90 个此类实体,所以我认为它不会带回 1000 个。
    • 它不会带回 1000 个,但如果有一千个,我确实需要将它们全部拉出。但是,是的,在这种情况下,我需要制定一些分页。但该网站不太可能覆盖这么多用户。
    • 另外,我尝试将 fetch 更改为 100(因为我总共只有大约 90 个),性能与尝试 fetch 1000 相同。
    【解决方案4】:

    可能是图像(和/或 Text 属性)需要时间来加载和编组到对象中,具体取决于这些属性的大小。

    一等奖:就像别人说的那样使用内存缓存。然后仅在第一次命中时才会产生开销。

    二等奖:我不确定您的图片更改频率以及您可能有多少,但您可以考虑将它们作为静态文件上传并在 HTML 中简单地链接到它们。然后它只是来自浏览器的 HTTP GET - 开销要低得多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-10
      • 2016-05-17
      • 2018-04-02
      • 2021-07-07
      • 2017-07-19
      • 1970-01-01
      • 2013-05-17
      • 1970-01-01
      相关资源
      最近更新 更多