【问题标题】:Foreach and SqlConnection Using StatementForeach 和 SqlConnection 使用语句
【发布时间】:2015-10-31 04:25:22
【问题描述】:

我正在尝试找出哪个运行效率更高。我有一个foreach 的表格,我想知道它应该在我的使用范围之外还是在其中。以下示例。

using (SqlConnection) 内的foreach

foreach (string tableName in desiredTables)
{
    using (SqlConnection connection = new SqlConnection(cloudConnectionString))
    {
        connection.Open();

        string query = string.Format("SELECT id, active, createdon, modifiedon FROM {0}", tableName);
        using (SqlCommand cmd = connection.CreateCommand())
        {
            cmd.CommandText = query;
            cmd.CommandType = CommandType.Text;
            SqlDataAdapter dAdapter = new SqlDataAdapter(cmd);

            try
            {
                dAdapter.Fill(dSet, tableName);
            }
            catch
            {
                throw;
            }
        }
    }
}

using (SqlConnection) 内部的foreach 相比:

using (SqlConnection connection = new SqlConnection(cloudConnectionString))
{
    connection.Open();

    foreach (string tableName in desiredTables)
    {

        string query = string.Format("SELECT id, active, createdon, modifiedon FROM {0}", tableName);
        using (SqlCommand cmd = connection.CreateCommand())
        {
            cmd.CommandText = query;
            cmd.CommandType = CommandType.Text;
            SqlDataAdapter dAdapter = new SqlDataAdapter(cmd);

            try
            {
                dAdapter.Fill(dSet, tableName);
            }
            catch
            {
                throw;
            }
        }
    }
}

我正在尝试对此进行优化,以便更快地从数据库中提取数据,但我不确定推荐/更好的方式。建议会很棒。

【问题讨论】:

  • 哪个更快?尝试测量每个版本一百万次。
  • 这是一个重复的任务,还是一个很少使用的操作?
  • 仅供参考,catch { throw; } 毫无意义 - 甚至可能没有 catch 块(或在这种情况下为 try)。
  • 真的吗?与从池中打开连接一样快,为什么要做多次。至于那你为什么要循环使用SqlCommand?为什么你一次只删除一个表而不是一个 DataSet?

标签: c# sql optimization foreach


【解决方案1】:

您必须尝试并对其进行测量才能确定,但​​我怀疑无论哪种方式您都会看到巨大的差异。连接由 .NET 汇集,因此在循环中创建它们(我假设您只有少数表,而不是数百个)不应成为重大瓶颈。您可能会在网络 I/O 和实际填充 DataSet 上花费更多时间(确实有很多开销)。

底线 - 一种可行的方法(因此您可以恢复使用)并尝试多种方法,看看一种方法是否对应用程序产生显着影响整体

【讨论】:

    【解决方案2】:

    通常,在网络环境中多次打开和关闭数据库连接可能会很昂贵(连接数据在您的网络中传输几轮,C# CLR 必须多次分配和释放资源,垃圾收集有更多工作要做稍后...),因此您应该尝试通过将其置于循环之外来重用您的数据库连接。

    【讨论】:

    • 这并不像你说的那么糟糕。数据库连接由 .NET 汇集,因此创建它们通常不是一个非常昂贵的过程(至少相对于网络 I/O 所花费的时间而言)。长时间保持单个连接打开通常更糟糕
    • 好吧,至少我们在循环外调用 Open() 和 Close() 对与在循环中多次调用它的情况是不同的。调用一次与调用数百次,即使在.NET 连接池的帮助下,在 CPU 中花费的持续时间也大不相同。您可以轻松编写一个简单的循环来验证事实。
    • .NET 将尽可能地尝试重用您的池连接,但这并不意味着这会一直发生并且没有任何成本。当我们在一个大型网站的组件中使用代码时,如果我们反复关闭()然后打开()连接,我们可能无法获得之前打开的相同连接。如果在我们关闭它之后,有人拿走了它,突然所有可用的连接都被使用了,会发生什么?我们的 Open() 方法必须等到其他资源释放或超时发生。那么,为什么不明确地重用连接 FOR THE LOOP 只是为了避免这种情况呢?
    猜你喜欢
    • 2014-05-28
    • 2011-03-05
    • 1970-01-01
    • 2014-02-03
    • 2015-03-31
    • 2021-08-27
    • 1970-01-01
    • 2010-12-05
    • 2014-05-28
    相关资源
    最近更新 更多