MySQL - 单个连接与池

时间:2016-04-27 12:52:28

标签: java mysql database multithreading

由于我之前已经回答过一些关于MySQL同步特性的问题,我开始质疑人们使用连接池的原因,如果在我的场景中我应该转移到池中。

目前我的应用程序保持单个连接处于活动状态。在我的应用程序中只有一个connection, statement, and result set被回收。我的所有数据库任务都放在一个队列中,并在一个单独的线程上重新执行。 一个用于数据库查询的线程,一个用于数据库访问的连接。如果连接有问题,它将处理连接并创建一个新连接。

根据我的理解,不管有多少查询被发送到MySQL进行处理,它们都将按接收顺序同步处理。如果这些查询来自单个源或多个,则无关紧要,它们将按接收的顺序执行。

有了这样的说法,当有多个连接和线程将查询粉碎到数据库的处理队列时,无论如何都要逐个处理它们,这是什么意思。查询在完成处理之前的查询之前不会执行,并且在我不使用池的情况下也是如此,在上一个查询完成处理之前不会执行下一个查询

现在你可以说:

  

处理MySQL查询提供的结果所花费的时间将增加查询执行之间的时间。

这显然是正确的,这就是我有一个处理查询结果的工作线程的原因。查询完成后,我将结果转换为Map<>格式并从内存中释放语句/结果集并开始处理下一个查询。 Map<>被发送到单独的工作线程进行处理,因此它不会使查询执行线程拥塞。

任何人都可以告诉我,我做事的方式是否正常,以及我是否应该花时间转移到连接池而不是持久连接。最重要的是为什么。我严格按照信息目的启动此主题。

编辑:2016年4月29日

  

我想补充一点,我知道连接池是什么,但是当表在查询处理期间锁定来自所有连接的请求时,我更好奇使用池而不是单个持久连接的好处首先。

3 个答案:

答案 0 :(得分:0)

只是尝试使用StackOverflow,但是,

在与数据库的每个连接中,大多数情况下,它都处于空闲状态。当您在与INSERTUPDATE表的连接中执行查询时,它会锁定表,从而阻止并发编辑。虽然这很好,并且全部阻止数据覆盖或损坏,但这意味着在第一个连接/查询仍在运行时,没有其他连接可以进行编辑。

然而,开始一个新的连接需要时间,并且在较大的基础设施试图撇去并剥掉所有多余的时间浪费,这是不好的。因此,连接池是处于空闲状态的整组连接,为下一个查询做好准备。

最后,如果您正在运行一个小项目,那么通常没有理由建立连接池,但是如果您运行的是一个大型网站UPDATEINSERT s毫秒,连接池减少了开销时间。

答案 1 :(得分:0)

稍微related answer: 池可以执行其他“连接运行状况检查”(通过检查SQL异常代码) 并刷新连接以减少内存使用(请参阅答案中关于“maxLifeTime”的说明)。 但是所有这些事情可能不会超过使用一个连接的简单方法。

要考虑的另一个因素是(阻塞)网络I / O时间。考虑这个(粗略)场景:

client prepares query --> client sends data over the network
--> server receives data from the network --> server executes query, prepares results
--> server sends data over the network --> client receives data from the network
--> client prepares resultset

如果数据库是本地的(与客户端在同一台机器上),那么网络时间几乎不可察觉。 但是,如果数据库是远程的,则网络I / O时间可以变得可测量并影响性能。 假设隔离级别为“已提交读取”,则并行运行select-statements可能会变得更快。 根据我的经验,同时使用4个连接而不是1个通常可以提高性能(或吞吐量)。 这取决于您的具体情况:如果MySQL确实只是等待锁定才能被释放, 添加额外的连接在速度方面不会做太多。 同样,如果客户端是单线程的,客户端实际上可能无法察觉到任何明显的速度改进。

这应该很容易测试:将一个程序的执行时间与使用1个连接的1个线程进行比较,以执行X量的select-queries (即重新使用当前程序)与另一个程序使用4个线程,每个线程使用1个单独的连接 执行相同的X-amount select-queries除以4个线程(或者只是并行运行第一个程序4次)。

关于连接池的一个注释(如HikariCP):池必须确保没有事务 连接返回到池时保持打开状态,这可能意味着每次将连接返回到池时都会发送“回滚” (关闭)当自动提交关闭并且之前未发送“提交”或“回滚”时。 这反过来可以增加网络I / O时间而不是减少它。所以一定要测试 自动提交或确保在查询或查询集完成后始终发送提交或回滚。

答案 2 :(得分:0)

连接池和持久连接不是一回事。 一个是SQL连接数量的限制,另一个是单个管道问题。 问题通常是将SQL输出传输到服务器所花费的时间,而不是查询执行时间。因此,如果打开两个cli SQL客户端并触发两个查询,一个具有大输出,一个具有小输出(在该序列中),较小的一个完成,而较大的一个仍然滚动其输出。 这里的要点是,多个连接确实解决了上述情况的问题。

当您有多个请求查询的前端请求时,您可能更喜欢持久连接,因为它为您提供了不同连接(大型与小型输出)的Multiplex优势,并防止了会话设置/拆卸的开销。

连接池API具有内置的错误检查和处理功能,但大多数API仍然希望您手动声明是否需要持久连接。

因此实际上有3个变量,池,持久性和配置参数通过API。一个人必须混合和匹配池大小,持久性和连接数以适应一个人的环境