与几个较小的 SQL 相比,使用连接执行单个 SQL SELECT 是否更有效


Is it more efficient to do a single SQL SELECT with joins vs several smaller SQLs?

我的代码使用长SELECT语句,这些语句通常使用某种idkey来连接数据,将各种表LEFT JOIN在一起。

然后将此 SQL 的结果输入到 PHP 类构造中。 结果可以包含例如

  • 曲线系数
  • 产品参数
  • 测试数据

我拥有的代码结构不是很好,所以我正在考虑将其拆分为几个(即本例中为 3 个)较小的简单 SQL SELECT,而不是一个长SQL查询。 好处是代码将更清晰,更易于理解,并且可以更好地重构为更小更有意义的类和函数。

但在我开始拆除大量外观相似的 SQL 语句之前,我想检查一下从性能的角度来看,分解 SQL 是否有意义。 因为,或者,我可以保持长 SQL 原样,并且仍然能够将我的代码重构为更有意义的类和函数,但只是不同。

问题:最后,考虑到 PHP 和 MySql 如何协同工作,使用具有多个连接的较长 SQL 而不是对较短 SQL 的多次调用(可能没有任何连接)是否有任何可衡量的好处?

与大多数MySQL一样,这取决于。你真的需要测试才能找到答案。

提交到数据库的每个 SQL 查询都有开销成本(解析、准备查询、执行、准备结果、响应提取、清理的开销)。这就是为什么用很少的查询(例如,一个非常紧密的循环,每个查询获取一行)到数据库的大量往返比返回所有行的单个查询效率低得多的原因。

另一方面,直到MySQL 5.6,优化器使用的唯一连接方法是嵌套循环。如果没有合适的索引或误导性的统计数据...

"大型"查询(即涉及数十个表和数百万行的查询)在性能方面可能存在问题。

但是,数据库服务器通常在大小合理且索引适当的集上通过正常的连接操作来充分执行。数据库服务器上的连接操作通常比应用程序服务器上运行的代码执行的等效操作更有效。

问:是否有可衡量的差异?

答:理论上可以。 (理论上,理论和实践之间没有区别。在实践中,有。

运行一个查询与数千个查询相比的好处是开销更少,并且可以测量差异。

一个查询的缺点是查询可能需要MySQL做很多工作,以至于性能变得冰冷,我们有时可以通过将查询分解为可管理的块来提高效率。我们通常不会注意到几个查询执行的开销......当我们进入数千次数据库往返时,我们会遇到性能和可伸缩性问题。

要真正找出答案,既然您已经在考虑分解查询,请继续将查询分解为您计划运行的各个查询,并进行测试。

(我关注的是数据库服务器方面的效率,而不是应用程序服务器的性能......我也一直在考虑数据库服务器在一个主机上,应用程序服务器和数据库之间的网络连接......毫秒级网络往返在数以万计的往返时开始加起来。

根据我的基准

  • 长 SQL 语句的 10,000 x 执行需要 1.5 秒
  • 10,000 x 执行等效的较短 SQL 语句需要 2.43 秒

对于我的具体情况,长SQL获胜,很可能是由于PHP通常处理更多的代码行。