代码之家  ›  专栏  ›  技术社区  ›  Jiaaro

往返mysql的开销?

  •  3
  • Jiaaro  · 技术社区  · 15 年前

    因此,我已经构建了一段时间的django应用程序,并且喝了一些很酷的辅助工具:只使用ORM,从不编写定制的SQL。

    一旦你有了大量用户特定的内容(如照片、朋友、其他数据等),网站的主页(用户将花费80%-90%的时间的主要界面)就会变慢。

    所以我在SQL记录器中弹出(预先安装了pinax,我只是在设置中启用了它),想象一下当它报告结束时我的惊讶。 500个数据库查询 !!对于手工编码的SQL,我几乎从未在最复杂的页面上运行过超过50个。

    事后看来,这并不令人惊讶,但这似乎不太好。

    …即使只有十几个查询需要1毫秒+

    所以我想知道, 往返mysql的开销是多少 ?Django和MySQL正在 同一服务器 所以不应该有任何与网络相关的开销。

    4 回复  |  直到 15 年前
        1
  •  2
  •   S.Lott    15 年前

    有一些方法可以减少查询量。

    1. 使用 .filter() .all() 获取一堆东西;在视图函数(或模板通过 {%if%} )python可以比mysql更快地处理一批行。

      “但我可能会向模板发送太多信息”。是的,但您将执行更少的SQL请求。测量看哪个更好。

      这是您在编写SQL时经常做的事情。这并不是错误的——它不会破坏ORM——但它优化了底层数据库工作,并将处理过程放入视图函数和模板中。

    2. 避免在模板中进行查询导航。当您执行foo.bar.baz.quux时,SQL用于获取 bar 关联 foo 然后 baz 酒吧 然后 quux 关联 巴兹 . 您可能需要谨慎地减少这个查询业务 过滤器() 以及在视图函数中组装有用的元组的python处理。

      同样,这也是您手工制作SQL时经常做的事情。在这种情况下,您可以在视图函数中收集更多批ORM管理对象,并使用Python进行过滤,而不是通过许多单独的ORM请求进行过滤。

      这不会破坏ORM。它将使用概况从许多小查询更改为几个大查询。

        2
  •  4
  •   cethegeek    15 年前

    仅仅因为您使用的是ORM,并不意味着您不应该进行性能调优。

    我有——像你一样——我的一个应用程序的主页性能很差。我看到我正在做数百个查询来显示那个页面。我看了看我的代码,意识到在使用 select_related() 我的查询会带来更多我需要的数据——我从数百个查询到数十个。

    您还可以运行一个SQL事件探查器,看看是否有索引可以帮助您最常见的查询——您知道,标准的数据库资料。

    我想缓存也是你的朋友。如果很多页面没有改变,您是否需要每次查询数据库?

    如果其他的都失败了,记住:ORM是伟大的,是的-你应该尝试使用它,因为它是姜戈哲学; 但你还没有结婚 .

    如果您真的有一个研究和调优ORM导航没有帮助的用例,如果您确信可以用一个标准查询做得更好:对该用例使用原始SQL。

        3
  •  3
  •   BeWarned    15 年前

    每个查询的开销只是图片的一部分。Django和MySQL服务器之间的实际往返时间可能非常短,因为大多数查询在不到一毫秒的时间内返回。更大的问题是,向数据库发出的查询数量可能会很快压倒它。一个页面的500个查询是很重要的,即使50个对我来说也很重要。如果10个用户查看复杂的页面,那么现在最多可以查询5000个。

    当调用者从广域网访问数据库时,到数据库服务器的往返时间更是一个因素,在广域网中往返时间很容易在20毫秒到100毫秒之间。

    我肯定会考虑使用某种缓存。

        4
  •  1
  •   Tendayi Mawushe    15 年前

    在数据库调用中总是有开销,在您的情况下,开销不是 那个 坏的,因为应用程序和数据库在同一台计算机上,所以没有网络延迟,但仍然有很大的成本。

    当您向数据库发出请求时,它必须准备通过执行一些操作来服务该请求,包括:

    • 将资源(内存缓冲区、临时表等)分配给将处理请求的数据库服务器连接/线程,
    • 取消对SQL和参数的序列化(即使在一台计算机上也是必需的,因为这是一个进程间请求,除非您使用的是嵌入的数据库)
    • 检查查询是否存在于查询缓存中,如果不优化它并将其放入缓存中。
      • 还要注意,如果查询没有参数化(即值与SQL不分离),这可能会导致语句的缓存未命中,这意味着每个请求都会导致每次分析和优化查询。
    • 处理查询。
    • 准备并将结果返回给客户。

    这只是大多数数据库管理系统处理SQL请求所做的事情的概述。即使查询本身运行得比较快,也会产生500倍的开销。即使是到本地数据库的底层数据库交互也不像您期望的那样便宜。