为什么在一个请求中建立多个数据库连接是一种不好的做法?
关于PHP中的Singletons的讨论使我越来越多地考虑这个问题。大多数人指示我们不应在一个请求中建立一堆数据库连接,而我只是好奇推理是什么。我首先想到的是脚本向数据库发出这么多请求的开销,但随后我提出了自己的问题:多个连接是否会使并发查询更有效?
来自某些知情人士的一些答案(有证据,有证据的人)怎么样?
解决方案
回答
这是建立连接,传输数据然后拆除数据的成本。它会吞噬表现。
很难获得证据,但请考虑以下内容...
假设建立连接需要x微秒。
现在,我们要发出多个请求并来回获取数据。假设一个连接和多个连接之间的传输时间差异可以忽略不计(仅出于争论的目的)。
现在,假设要花费y微秒的时间才能关闭连接。
打开一个连接将花费x + y微秒的开销。开许多将花费n *(x + y)。那会延迟执行。
回答
我想这是因为请求不是异步发送的,因为请求是在服务器上迭代完成的,每次都阻塞,所以我们每次都必须为每次创建连接支付开销一次...
在Flex中,所有Web服务调用都会自动异步调用,因此通常会看到多个连接,或者在同一连接上排队请求。
异步请求通过更快的请求/响应时间来减轻连接成本……因为如果没有一些线程就无法在PHP中轻松实现这一点,那么性能损失会更大,然后简单地重用相同的连接。
那是我的2美分...
回答
建立数据库连接通常非常繁重。许多事情都在后台进行(DNS解析/ TCP连接/握手/身份验证/实际查询)。
我曾经遇到过一些奇怪的DNS配置问题,该问题使每个TCP连接都花了几秒钟才上。我的登录过程(由于架构复杂)花费了3个不同的DB连接来完成。有了这个问题,登录就花了很多时间。然后,我们重构代码以使其仅通过一个连接。
回答
我们从.NET访问Informix并使用多个连接。除非我们在每个连接上启动事务,否则它通常在连接池中处理。我知道这是非常特定于品牌的,但是大多数(?)数据库系统的即时访问都将尽其所能来汇集连接。
顺便说一句,由于跨数据库连接,我们确实存在连接计数问题。 Informix支持同义词,因此我们将常见的违规者作为同义词,并在服务器端处理了多个连接,从而节省了大量的传输时间,连接创建开销和(真正的症结)许可费用。
回答
数据库连接是有限的资源。一些数据库的连接限制非常低,浪费连接是一个主要问题。通过使用许多连接,我们可能会阻止其他人使用数据库。
此外,除非数据库服务器上有闲置的资源,否则在数据库上抛出大量额外的连接无济于事。如果我们有8个核心,而仅使用一个核心来满足查询,那么可以肯定的是,建立另一个连接可能会有所帮助。不过,我们更有可能已经在使用所有可用的内核。我们可能还会为每个数据库请求命中相同的硬盘驱动器,并添加其他锁争用。
如果数据库有类似高利用率的内容,那么添加额外的连接将无济于事。这就像在应用程序中产生额外的线程,而盲目希望额外的并发性将使处理速度更快。在某些情况下可能会出现这种情况,但在其他情况下,这只会使我们放慢速度,因为我们要对硬盘驱动器进行破坏,浪费时间进行任务切换并引入同步开销。