为啥数据库连接池比单个连接更好?

Posted

技术标签:

【中文标题】为啥数据库连接池比单个连接更好?【英文标题】:Why are database connection pools better than a single connection?为什么数据库连接池比单个连接更好? 【发布时间】:2013-12-20 21:45:22 【问题描述】:

我目前正在编写一个需要访问数据库才能处理请求的多线程应用程序。我看到很多人说使用包含许多持久数据库连接的池是这种类型应用程序的最佳选择,但我试图弄清楚为什么会出现这种情况。

请记住,我是在 Erlang 中设计这个应用程序的,所以我会大量使用线程/进程/工作者。

那么我们来比较两种情况:

    您有一个拥有单个数据库连接的线程。您的所有客户端处理线程都与该线程通信以进行数据库查询。

    您有一个线程池,每个线程都有自己的数据库连接。当客户端处理线程想要访问数据库时,它会从池中获取这些线程之一,并使用它来查询数据库。

在第一种情况下,我看到很多人说这很糟糕,因为让一个线程处理所有与数据库相关的查询反过来会导致瓶颈。但我的困惑如下:那个单线程的瓶颈实际上不是数据库本身吗?如果线程所做的只是通过其连接句柄查询数据库,那么等待数据库响应请求不是延迟的主要来源吗?在这个问题上抛出更多的连接线程将如何解决它?

【问题讨论】:

【参考方案1】:

数据库可能具有完善的多线程能力。使用连接池允许:

    利用数据库的多线程/负载平衡能力 避免反复设置和断开连接的开销

当数据库为多个连接提供服务时,它可以自行决定如何确定请求的优先级。想象一下这种情况:

    用户 A 从表 A 中请求一组 100,000 行的记录 用户 B 从表 B 中请求一组 50 行的记录 用户 C 更新表 A

如果使用多个连接,DB 可以利用 (1) 和 (2) 可以同时发生的事实,并且用户 B 获得他的 50 条记录,而无需等待用户 A 获得他的全部 100,000 条记录。只有用户 C 必须等待用户 A 完成。

此外,建立和断开 TCP 连接是一项相对昂贵的任务。使用池允许一个用户释放资源而无需断开 TCP 连接,因此下一个用户不必等待新连接。不过,您的单线程方法不会从连接池的这一方面受益。

【讨论】:

嗯,是的,很好的答案,在这种情况下,我并没有真正考虑数据库的内部结构。 为什么不能通过单个连接来实现,假设这是某种异步连接,因此您可以同时通过它发送所有 3 个查询?我想答案真的取决于数据库驱动程序,所以最好不要冒险使用坏驱动程序并让数据库处理它才是正确的答案。但这只是猜测。 @inf3rno:大多数连接在内部不是异步的。客户端发送一个命令并获得一个结果集(或其他响应)。一些驱动程序支持“MARS”——多个活动结果集,它允许在处理前一个结果集之前发送进一步的查询,但我认为这些通常是驱动程序功能(很可能通过多个同时连接实现),而不是后端数据库本身。 @BrianA.Henning 是的,就像我想的那样,大多数驱动程序不适合这个,数据库可以更好地决定它。我有一个关于推荐多少连接的问题,也许你可以回答它:***.com/questions/61472013/… 虽然我想我需要寻找研究论文而不是 SO 问题。

以上是关于为啥数据库连接池比单个连接更好?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我收到“无法从传输连接读取数据”

SQL中,多表连接查询和不相关子查询从查询效率上来说,哪种查询的效果更好?为啥 ?

追光者系列主流Java数据库连接池比较及前瞻

为啥在具有多个连接的 WHERE 子句中,子查询比文字值执行得更好?

python数据库连接池

MySQL 连接器 (Python):每个查询的新数据库连接与单个连接