【问题标题】:Should I keep this "GlobalConnection" or create connection for every query?我应该保留这个“GlobalConnection”还是为每个查询创建连接?
【发布时间】:2013-06-07 15:21:32
【问题描述】:

我继承了一个使用 ADO 连接到 SQL Server 的旧版 Delphi 应用程序。

应用程序有一个“全局连接”的概念 - 即它在开始时打开的单个连接,然后在应用程序运行的整个过程中保持打开状态(可能是几天、几周或更长时间。 ...)

所以我的问题是:我应该保持这种做事方式还是应该切换到“连接-查询-断开”的做事模式?有关系吗?

切换将是一项艰巨的任务,但如果它意味着更好的性能、数据管理等,我会这样做。

【问题讨论】:

  • 您现在发现问题了吗?它是一个什么样的应用程序?如果它是具有单个用户(或 Windows 服务)或 Web 应用程序的 winforms 应用程序,则会有所不同。
  • 我预计性能会因为永久连接和断开连接的开销而变差。
  • 这是一个用 Delphi 编写的客户端/服务器应用程序。
  • 我应该补充一点,该应用存在主要的数据库性能问题。
  • 需要多个 ADO 连接的一件事是,如果您的应用程序是多线程的,因为 ADO 连接不能被两个线程使用。

标签: sql-server delphi connection


【解决方案1】:

嗯,这取决于您期望从中获得什么,以及它是什么类型的应用程序。

使用单个长时间运行的连接并没有什么特别的问题,只要应用程序可以优雅地处理断开连接并在无法重新连接时恢复或记录/通知。

connect-query-disconnect 设置的问题在于,您在每个查询上都增加了连接和断开连接的开销。这会减慢速度,并且在交互式 GUI 应用程序中,用户可能会注意到额外的开销。如果还没有授权,您还必须确保透明地处理授权。

同时,如果您可以将所有查询推送到后台线程并异步更新 GUI,则可能会获得交互式性能提升。如果由于查询被序列化而出现争用,您也可以相当容易地迁移到连接池系统并进一步改进事情。不过,这会带来相当高的复杂性成本,因此现在您要平衡收益与所涉及的工作相比。

现在,我的最终反应是“如果它没有坏,就不要修复它。”按照您提议的方式进行更改需要大量工作——这个应用程序的用户可以获得多少收益?是否还有其他问题需要解决以使他们受益更多?

编辑:好的,所以它坏了。好吧,至少慢一点,这对我来说都是一样的。如果您已经排除了 SQL Server 本身的问题,并且查询的执行速度尽可能快(即 DB 模式是健全的,正确的索引可用,查询不是完全脑死,服务器有足够的 RAM 并且足够快I/O、网络不不稳定等),那么是的,是时候想办法提高应用程序本身的性能了。

简单地转移到连接-查询-断开连接会使事情变得更糟,您发出的查询越多,下降的幅度就越大。听起来您需要重新构建应用程序,以便您可以运行更少的查询、在后台运行它们、在客户端上更积极地缓存,或者三者的某种组合。

不要忘记让客户端性能更好意味着服务器端性能变得更加重要,因为如果客户端开始建立多个连接并并行发出多个查询,它可能会处理更高的负载。

【讨论】:

    【解决方案2】:

    正如弗雷泽先生之前所说的那样——一个全球性的联系本身还不错。

    如果你打算改变,首先要发现什么是问题所在。让我们看一些场景:

    1

    某些屏幕(IOW:一组 1..n 表单在业务实体中操作)速度很慢。可能的原因:

    1. 过滤不充分导致不必要地从数据库中提取大量记录。
    2. 记录数还可以,但渲染它需要太多时间。解决方案:更快的控件或智能渲染(例如:虚拟列表视图)
    3. 每次打开屏幕时查询过多。可能的解决方案:使用 TClientDatasets(或任何内存中的数据集)来保存不经常修改的查找表。为更广泛的表提供更复杂的缓存或在其他线程中打开这些数据集可以缩短响应时间。
    4. 在绑定了控件的数据集上滚动可能会很慢(请记住,因为这些小细节很容易忘记)。

    2

    整个应用程序都会变慢。清单:

    1. 网卡正常吗?即使在结构良好的网络上,一些网卡故障也会造成严重破坏,因为它们会在线路上产生不必要的噪音。
    2. [MSSQL DBA HAT ON] 下一个受到攻击的是 SQL Server。要求 DBA 跟踪块和死锁。注册慢查询并加快处理速度。这与#1.1 和#1.3 直接相关
    3. 检测是否有一些天真的开发人员在内部事务中完成了SELECT。在读取提交隔离中,这只是开销,因为它会创建更多的网络流量。打开查询,检索数据并关闭数据集
    4. 如果可以,请查看数据库架构。
    5. 是否在应用程序上对大量记录进行了任何数据绑定操作(例如,标注某些/大部分/所有产品的价格)?对查询进行 SP 或重构操作,速度会快得多,并且会减少整个服务器的负载。
    6. 对一组记录进行大量操作?了解如何在服务器上立即执行该操作,而不是一一记录。在MSSQL MVP Erland Sommarskog's article on array and list on MSSQL 上查看最常用的替代方案。
    7. 提防带有WHERE 的查询,例如:WHERE SomeFunction(table1.blabla) = @SomeParam。大多数时候,那些不会使用导致读取整个表以选择所需数据的索引。如果是一个大表......在持久计算列上建立索引可以创造奇迹......[MSSQL HAT OFF]

    这就是我能想到的没有更多细节...... ;-)

    【讨论】:

      【解决方案3】:

      创建数据库连接是耗时的资源,经验法则应尽可能少地创建并尽可能重用。这就是为什么其他一些技术具有数据库连接池的原因,这些连接池通常在应用程序/服务启动时建立,然后尽可能长时间地保持并在线程之间共享。

      根据您的评论,该应用程序存在性能问题,但如果没有更多细节,很难提出任何建议。

      应该尝试确定什么是慢 - 是所有查询都很慢还是只是一些特定的? 如果只是一些特定的,则有一些相关性。

      我的 2 美分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-15
        • 1970-01-01
        • 1970-01-01
        • 2012-08-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多