为每个请求创建与 MS SQL 数据库的新 RJDBC 连接是不是存在性能/其他缺点?

Posted

技术标签:

【中文标题】为每个请求创建与 MS SQL 数据库的新 RJDBC 连接是不是存在性能/其他缺点?【英文标题】:Are there performance/other downsides in creating a new RJDBC connections to MS SQL database for each request?为每个请求创建与 MS SQL 数据库的新 RJDBC 连接是否存在性能/其他缺点? 【发布时间】:2013-08-31 21:12:59 【问题描述】:

我想了解通过 RJDBC (重新)使用与 MS SQL 数据库的 SQL 连接的最佳做法。

我可以想象三种可能的情况:

    将连接存储在全局变量中,初始化一次,在代码中随处使用 为每个请求创建一个新连接 做一些更复杂的事情,例如预填充开放连接池,并根据需要(重新)使用池中的连接。

我在一个有几十个客户端的闪亮应用程序中使用我的代码,如果我使用方法 1,我担心会发生不好的事情。所以我使用方法 2,为每个请求创建一个新的连接代码下面。

我可以看到这种方法的一些潜在缺点:性能、数据库资源负担等。但我可能过于谨慎,因为 R 是单线程的,即使在闪亮的使用场景中也是如此?

所以我的具体问题是:

A.我可以在我闪亮的应用程序中通过 RJDBC 安全地使用与 MS SQL 数据库的单一连接吗?

B.在上面的场景 2 中是否有任何真正的缺点(内存泄漏、性能等)?


NewConnection <- function() 
  file = NULL
    # make it work on three different OSes - Linux, MacOS, Windows 
    for (path in c('/Users/victor/Documents/R/sqljdbc_3.0/enu/sqljdbc4.jar',
          '/home/oracle/sqljdbc_3.0/enu/sqljdbc4.jar',
          'C:/Projects/jdbc/sqljdbc_4.0/enu/sqljdbc4.jar')) 
      if (file.exists(path)) 
        file = path
          break
      
    
  if (is.null(file))
    return(NULL)
  else 
    drv <- JDBC("com.microsoft.sqlserver.jdbc.SQLServerDriver", file)
      passwd <- GetUserNamePassword()
      conn <- dbConnect(drv, "jdbc:sqlserver://sql.server.address.com", 
          passwd$username, passwd$password)
      return(conn)
  


附:相关:How to manage a database connection in an R Package

【问题讨论】:

使用连接池。它可以工作并且已经过广泛的测试。这是扩展数据库连接的方式。 感谢@Namphibian 的提示。由于我从未在 R(或任何其他语言,就此而言)实现这一点 - 关于我应该如何开始的任何想法?例如。我应该如何测试哪些连接未使用?使用后如何“返回”与池的连接?欢迎任何提示。 大多数连接池都会透明地为您处理这个问题。您只需询问连接池,而不是从驱动程序获取连接。暂时不在电脑前。明天会回复一个正确的答案。 Namphibian 是对的。 AFAIK,除非在连接字符串中明确要求,否则默认情况下,每个连接都会检查连接池(由操作系统管理),然后在可用时回收现有连接。因此,您的应用程序可以根据需要“安全地”创建新连接(并在不再需要时丢弃它)。警告词(当您使用 Java 时),这可能仅在您的应用程序在 Windows 下运行时才是正确的;我不知道其他操作系统。 @deroby 我从来没有听说过 Windows 默认管理一个连接池。可以提供参考吗? 【参考方案1】:

很多问题:

1) 重用连接比每次使用都建立新连接要快。根据您的代码,这将稍微加快您的应用程序。但是重用连接更复杂。这就是很多人使用连接池的原因。

2) 如果您的程序运行时间较短,您可以使用一个连接,例如在一个全局变量中。如果您的应用程序是服务器应用程序(长时间运行),那么您需要保持连接,因为服务器可以关闭连接,如果没有人使用它,因为连接上没有流量。这可能发生在服务器应用程序的夜间。连接维护功能是连接池的一部分。

总结。 如果您的应用程序是简单的,不是多线程的,不是服务器应用程序,那么重用您的单个连接。否则,每次使用新连接或使用连接池。

【讨论】:

【参考方案2】:

考虑一下每次建立连接时幕后发生的事情可能会有所帮助:

必须建立 TCP/IP 连接(包括 DNS 查找和联系 SQL Server Browser 以获取命名实例的正确端口号) 用户需要经过身份验证和验证才能被授权连接 必须保留用于连接的服务器端资源(私有内存等)

因此,限制应用程序使用的连接数量是有意义的。

如果您的应用程序按顺序执行所有事务,您应该打开一次连接并重用它。为基于服务器的多用户应用程序使用连接池。

【讨论】:

以上是关于为每个请求创建与 MS SQL 数据库的新 RJDBC 连接是不是存在性能/其他缺点?的主要内容,如果未能解决你的问题,请参考以下文章

在db中为每个“对话”使用新的SQL表

如何将选择 sql 查询的结果转换为 ms 访问中的新表

将下拉菜单链接到 MS Access 中的新表单

PHP - MS SQL HTML - 在一行中显示每个客户的所有月份

从 PHP 请求名称为分音符号的 MS SQL 表

从MS-Access连接到sql server而不创建DSN