【问题标题】:Why is it bad practice to make multiple database connections in one request?为什么在一个请求中建立多个数据库连接是不好的做法?
【发布时间】:2008-08-26 16:53:53
【问题描述】:
关于 PHP 中的 Singletons 的讨论让我越来越多地思考这个问题。大多数人指示您不应该在一个请求中建立一堆数据库连接,我只是好奇您的推理是什么。我的第一个想法是您的脚本向数据库发出这么多请求的费用,但随后我提出一个问题来反驳自己:多个连接不会提高并发查询的效率吗?
从一些知情人士那里得到一些答案(有证据,伙计们)怎么样?
【问题讨论】:
标签:
database
resources
database-connection
【解决方案1】:
数据库连接是有限的资源。一些数据库的连接限制非常低,浪费连接是一个主要问题。通过使用许多连接,您可能会阻止其他人使用数据库。
此外,除非数据库服务器上的资源处于空闲状态,否则向数据库添加大量额外连接也无济于事。如果您有 8 个内核并且只有一个用于满足查询,那么可以肯定,建立另一个连接可能会有所帮助。不过,更有可能的是,您已经在使用所有可用的内核。您还可能会为每个 DB 请求访问同一个硬盘,并添加额外的锁争用。
如果您的数据库有任何类似高利用率的东西,那么添加额外的连接将无济于事。这就像在应用程序中产生额外的线程一样,盲目地希望额外的并发性会使处理速度更快。它可能在某些特定情况下,但在其他情况下,它只会让您在硬盘驱动器抖动、浪费时间任务切换以及引入同步开销时减慢您的速度。
【解决方案2】:
这是建立连接、传输数据然后将其拆除的成本。它会吃掉你的表现。
证据更难获得,但请考虑以下...
假设建立连接需要 x 微秒。
现在您要发出多个请求并来回获取数据。假设一个连接和多个连接之间的传输时间差异可以忽略不计(只是为了争论)。
现在假设关闭连接需要 y 微秒。
打开一个连接将花费 x+y 微秒的开销。打开许多将需要 n * (x+y)。这会延迟你的执行。
【解决方案3】:
设置数据库连接通常非常繁重。很多事情都在后台进行(DNS解析/TCP连接/握手/认证/实际查询)。
我曾经遇到过一些奇怪的 DNS 配置问题,导致每个 TCP 连接都需要几秒钟才能启动。我的登录过程(由于架构复杂)需要 3 个不同的数据库连接才能完成。有了这个问题,登录需要很长时间。然后我们重构了代码,让它只通过一个连接。
【解决方案4】:
我们从 .NET 访问 Informix 并使用多个连接。除非我们在每个连接上都启动一个事务,否则它通常是在连接池中处理的。我知道这是非常特定于品牌的,但大多数(?)数据库系统的 cilent 访问将尽其所能汇集连接。
顺便说一句,由于跨数据库连接,我们确实遇到了连接计数问题。 Informix 支持同义词,因此我们将常见违规者同义,并且多个连接在服务器端处理,从而节省了大量传输时间、连接创建开销和(我们情况的真正症结)许可费用。
【解决方案5】:
我认为这是因为您的请求不是异步发送的,因为您的请求是在服务器上迭代完成的,每次都阻塞,您必须支付每次创建连接的开销,当您只有做一次...
在 Flex 中,所有 Web 服务调用都是自动异步调用的,因此您经常会看到多个连接,或者在同一个连接上排队请求。
异步请求通过更快的请求/响应时间来降低连接成本...因为在没有线程的情况下您无法轻松在 PHP 中实现这一点,因此性能损失比简单地重用相同的连接更大.
这是我的 2 美分...