每个页面加载 20 个 SQL 查询真的被认为很多吗? [关闭]

Posted

技术标签:

【中文标题】每个页面加载 20 个 SQL 查询真的被认为很多吗? [关闭]【英文标题】:Is 20 SQL Queries per page load really considered a lot? [closed] 【发布时间】:2010-09-25 10:39:38 【问题描述】:

我在Behold WordPress, Destroyer of CPUs 上阅读 Jeff Atwood 的博客,看到那里的许多人认为每页加载 20 个 SQL 查询已经很多了。现在,对于具有自动建议、自动刷新数据、自定义页面和厨房水槽的高度动态页面,每页的平均查询量是多少?

举个简单的例子,A​​mazon.com 实际上用他们认为我会购买的东西来定制我的主页。对我来说,这看起来并不只是对首页使用 5 个或更少的查询。

我还是数据库的新手,所以如果我遗漏了一些明显的东西,请告诉我。

【问题讨论】:

Amazon 有点特殊——别管 SQL 查询,它在主页上每次点击会执行多少 Web 服务请求?我听说过 100 多个,但我找不到链接。重要的指标是加载时间,而不是请求数量,亚马逊的芯片比你多得多…… 【参考方案1】:

您通常可以在两三个大查询中而不是二十个小查询中获取所有数据。最小化查询量与编写优化查询以最大化性能一样重要,如果不是最重要的话。

当然,您应该始终分析查询计划并以优化查询为目标,无论它们大小。

问题在于,设计糟糕的网页会执行许多查询,每个微小的任务都会执行一个查询,这些查询很容易被归类为一个查询。

例如,设计不佳的 *** 可以执行查询以获取它将显示在主页上的所有问题 ID,然后针对每个问题执行一次查询以获取摘要和投票。然后你很容易有 20 个无用的查询。一个设计良好的人会执行一次查询,获取有关它将显示的所有问题的所有信息。

当然,良好的缓存会降低这一切的影响,这是所有大型网站都会做的事情,这样您实际上可以进行大量查询并仍然获得不错的性能。

【讨论】:

组合大量查询的问题是您需要小心组合代码的方式。不要组合不相关的东西,否则你可能会得到难以分解的耦合代码。 我完全同意你所说的原则。我要补充一点,这取决于事情的不相关程度,以及可以实现多大的(以及需要的)性能增益。如果真的有必要,你总是可以在代码而不是 SQL 上将事情分开。【参考方案2】:

我的经验法则是尽可能将首页数量控制在 5 到 7 个以下,具体取决于网站的类型。

内部页面,根据他们的需要可能会有更多,但我会尽我所能将其保持在 20 以内。

但是,与此同时,取决于您要执行的操作以及您对该信息执行的缓存类型,如果其中 15 个被大量缓存,则 20 可能还不错...

【讨论】:

【参考方案3】:

答案实际上取决于几个关键因素: - 您网站的流量 - 支持您的 IT 预算 - 网站的复杂性和优化所需的资源

如果您的网站每天点击数次,那么谁会在意 20 次查询。 另一方面,如果您是亚马逊,那么您将以高昂的基础设施成本提供所需的内容。

世界上几乎所有其他人都介于这两个极端之间,必须根据自己的资源进行平衡。

我要说的唯一另一件事是缓存是你的朋友。

【讨论】:

【参考方案4】:

更多的是关于缓存。

如果您获得大量并发页面查看,并且每个页面查看执行大量查询,那么每次都访问数据库没有多大意义。单身的。 尤其是当大量返回的数据将通过时不时更改的半动态参考数据(与始终在变化的会话或实时数据相反)时。

您也可以使用 memcached 或类似的东西缓存这些数据库结果。您不一定需要缓存整个页面(尽管这是大多数 Wordpress 缓存插件所做的),因为这会破坏交互性,但您可以逐个数据地缓存。

还有优化查询的问题。尤其要避免可怕的 N+1 情况,即您对父记录执行一次查询,然后对其子记录的 每个 进行额外查询。仅在数据库之间往返的延迟就会影响您的页面渲染性能,更不用说对数据库本身造成影响了。

【讨论】:

【参考方案5】:

如果您必须进行 20 次查询,那就这样吧,但如果它是头版,我会有点紧张。

在可能的情况下组合查询会有所帮助,但考虑缓存是最重要的部分。

我目前正在升级一个站点,其中每年要查询数千次每年更改 5 或 6 次的数据,使用一些非常讨厌的 SQL 将其制成树,但可以将其保存为大约 200k 的树结构内存。 (首页上也有 700k 的视图状态,但那是另一回事了……)这些都是无缘无故地削弱网站的东西。

因此,关于您应该或不应该执行多少查询并没有一个神奇的数字,但请仔细考虑其中的每一个,即使您将其中一些仅缓存 5 分钟,如果有的话,这将产生巨大的影响你点击了digg的首页。

当您的网站处于压力之下时,仅对 1 个查询进行 5 分钟的缓存就可以消除数千个数据库命中。

【讨论】:

【参考方案6】:

鉴于没有使用 Ajax,每个页面都是原子的,我发现在 3 个或更少的查询中生成相当复杂的页面并不难。从概念上讲,一个典型的页面集包括:

    上下文信息(与会话和其他全局状态相关); 标题(以及相关的 1:0-1 连接); 详细信息(1:M 从 2)。

这需要提前计划;但另一方面,在大多数情况下,它是一个简单的重构练习。

【讨论】:

【参考方案7】:

查询的数量并不总是那么重要。这就是你处理连接的方式。如果您有连接池,那么它真的没关系,服务器的物理位置很重要。如果您的服务器在数据中心中彼此相邻,那么建立连接可能非常快。如果您的网站是一个数据库驱动的网站,那么您的网站大部分时间都花在等待连接打开和获取数据上。图打开一个连接需要100 - 300ms。因此,如果您必须为每个数据库访问打开 20 个连接,那么仅打开和关闭连接就需要 4 到 6 秒。

由于 Jeff Atwood 使用的是 LINQ,我假设他只打开一个连接,执行他的 20 个查询,然后关闭连接。这一切可能发生得很快。

此外,Jeff 的数据库在同一台物理机器上运行,并使用内部机器通信与数据库而不是网络通信,因此实际上不会出现与 TCP 类型连接打开相关的任何延迟。 (他几周前在 Hanselminutes 播客上谈到了这一点。)

我的一个站点使用 LINQ 和数据库在同一个盒子上进行了类似的配置。当我在本地计算机上运行该站点时,在另一个状态下访问服务器上的数据库时,加载几个数据繁重的页面最多需要 6 秒。当我在服务器上运行网站时,页面加载不到一秒钟,因为一切都是服务器本地的。

【讨论】:

【参考方案8】:

这取决于您正在构建的应用程序的类型、查询的复杂性以及您的数据库引擎和服务器允许您执行的操作。

如果您的数据库服务只允许您进行简单的 SQL 查询,那么对于一个小型的普通网页来说,少于 20 个查询就可以了,但如果它是您的大学网页或决策支持应用程序的网页,那么 60 个可能还不够.

如果您有权限并且您的 DBMS 有能力(例如 Oracle 等,与旧版本的 mysql 相比),超过 20 个查询要求您开始为繁重的任务创建存储过程、函数和触发器。在很多情况下你做不到,所以查询的数量自然会增加,你开始使用缓存来缓解服务器的压力。

例如,使用子查询在较少的查询中可以完成一些繁重的任务,但它们对数据库引擎来说确实很繁重。在某些情况下并不真正推荐它们,如果它们涉及数千条记录,则应谨慎使用。

Vinko 上面的例子可能适用于小型的、1 周的开发“项目”,但如果你问亚马逊,他们不使用你常见的 php/MySQL 开发包;前门后面是一个复杂的分布式计算和数据挖掘算法系统。如果你是新手,你不应该拿这样的大佬作为参考......

【讨论】:

【参考方案9】:

我在聚会上总是迟到,这有点晚了 5 年......

但对这个问题的直截了当的回答是,查询的数量少于查询所用的总时间。

如果一个包含多个连接和子查询的大型查询需要 20 秒才能执行,那么(我认为)20 个小查询总共需要 0.20 秒会好得多。

我发现管理较小的查询要容易得多,这主要是因为我缓存了每个查询,并且我可以一次又一次地重复使用单个查询中的数据.....

【讨论】:

但是,将请求发送到mysql进行查询是有代价的,mysql解析查询。该成本将在每个查询中重复一次。因此,即使查询很小,根据 mysql 和 webserver 之间的距离,这些查询的绝对数量也会导致缓慢。

以上是关于每个页面加载 20 个 SQL 查询真的被认为很多吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

SQL 死锁 - 高流量

计算 Laravel 5 的每个页面加载中的查询数

在每个 html 页面中执行相同 sql 查询的最佳方法是啥

SQL 计算 20 个工作日,删除银行存款并引用另一个查询

SQL 查询以获取每个位置的“最新”值

如何让SQL成为你很好的查询工具