【问题标题】:New connection for each query or one connection for all queries? (CommandBehavior.CloseConnection vs CommandBehavior.Default)每个查询的新连接还是所有查询的一个连接? (CommandBehavior.CloseConnection 与 CommandBehavior.Default)
【发布时间】:2011-06-01 11:08:56
【问题描述】:

我正在开发一个文本分析桌面应用程序,它集中查询本地数据库 (MSSQLCE 3.5)。当用户输入文本时,它应该会实时做出反应,因此我将 ADO.NET 与纯 SQL 结合使用并尝试获得最佳性能结果。

问题是:根据我的任务,我应该保留一个缓存连接(作为静态变量或单例)并使用CommandBehavior.Default 进行查询,还是应该为每个查询建立一个新连接并指定CommandBehavior.CloseConnection

我知道通常建议尽快关闭连接,但如果每分钟可能有数千个查询,例如当用户粘贴大量文本时,我真的应该这样做吗?

到目前为止,应用程序在 CloseConnection 上工作。现在我尝试将其转换为 CommandBehavior.Default 与单个连接。我可以看到一些小的性能加速,此时看不到任何问题,但我想知道在部署之前是否有任何附加条件。

// one cached connection for all queries
private static DbConnection _connection = null;
public static String MakeQuery()
{            
    if (_connection == null)
    {
        _connection = new SqlCeConnection(...);
        _connection.Open();
    }
    var cmd = new SqlCeCommand("...", _connection);
    using (var reader = cmd.ExecuteReader(CommandBehavior.Default))
    { 

    }
}

对比

// new connection for each query
public static String MakeQuery()
{            
    using (var connection = new SqlCeConnection(...))
    {
       connection.Open();            
       var cmd = new SqlCeCommand("...", connection);
       using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
       { 
           ...
       }
    }
}

【问题讨论】:

    标签: c# .net sql ado.net sql-server-ce


    【解决方案1】:

    就个人而言,当我需要从非 Web 应用程序快速连续地进行许多查询时,我更喜欢使用一个共享连接。

    唯一的问题是您必须密切关注它,因为它可能由于网络问题而意外关闭或者因为 SQL Server 认为最好关闭它。也就是说,您必须处理 StateChanged 事件。

    connection pooling 无论如何都是默认开启的。它应该为您处理所有这些问题。是的,池化确实增加了开销,但并不大。

    【讨论】:

    • 感谢您的快速回答!我将查看 StateChanged,但我想了解更多关于 SQL 服务器为何以及何时可以决定意外关闭连接的信息。此外,我不完全确定 SQL Compact Edition 3.5 SP2 提供程序是否支持池。您提供的链接讲述了(SQL SERVER 2008)。
    • @lonelyass 这篇文章让我觉得维护池的是 ADO.NET,而不是实际的数据提供者...I might be wrong。关于意外关闭连接,我好像错了,CE doesn't have a deadlock detection。我在回答中删除了这部分。
    • 我发现了一个关于我的主题的非常好的研究:csharponphone.blogspot.com/2007/01/… 你可以使用一个 SqlCeConnection 来提高性能,但是 SqlCeConnection 不是官方线程安全的,所以你必须为 db 创建一个线程安全的包装器-access,如果你想使用这个策略。 “一个有趣的旁注:我在手机上创建了一个测试应用程序,它在共享的 SqlCeConnection 上启动了 50 个线程并继续读取/写入随机数据位。没有抛出异常。当然,没有错误并不意味着它将永远有效。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多