【问题标题】:Stored Procedures not that fast?存储过程不是那么快吗?
【发布时间】:2009-11-25 21:41:28
【问题描述】:

呵呵。

我只是想通过使用存储过程来提高我的应用程序(.NET 3.5、C#)的性能。

所以我写了一个小测试应用程序来看看这些与看起来像这样的普通查询相比有多快:

    private static long _StartStored;
    private static long _EndStored;
    private static long _StartNormal;
    private static long _EndNormal;
    private static TimeSpan _StoredTime;
    private static TimeSpan _NormalTime;
    private static string[] _Stored = new string[102000];
    private static string[] _Normal = new string[102000];
    static void Main(string[] args)
    {
        Console.WriteLine("Querying 2000 normal queries");
        _SQLConnection = new SqlConnection(/*my_connection*/);
        _SQLConnection.Open();
        _StartNormal = DateTime.Now.Ticks;
        for (int i = 100000; i <= 102000; i++)
        {
            DataTable _ResultDataTable = new DataTable();
            SqlDataAdapter _SQLAdapter = new SqlDataAdapter(/*my_query*/, _SQLConnection);
            _SQLAdapter.Fill(_ResultDataTable);
            if (_ResultDataTable.Rows.Count > 0)
                _Normal[i] = _ResultDataTable.Rows[0]["row"].ToString();
        }
        _EndNormal = DateTime.Now.Ticks;
        _NormalTime = TimeSpan.FromTicks(_EndNormal - _StartNormal);
        Console.WriteLine("Total execution time: " + _NormalTime.ToString());
        //-----------------------------------------------------------------------------
        Console.WriteLine("Querying 2000 stored procedures");
        _StartStored = DateTime.Now.Ticks;
        SqlCommand _Cmd = new SqlCommand(/*my_sp*/, _SQLConnection);
        _Cmd.CommandType = CommandType.StoredProcedure;
        SqlParameter _Param = new SqlParameter("@param1", 0);
        _Cmd.Parameters.Add(_Param);
        for (int i = 100000; i <= 102000; i++)
        {
            _Cmd.Parameters["@param1"].Value = i;
            SqlDataReader _Reader = _Cmd.ExecuteReader();
            while (_Reader.Read())
            {
                _Stored[i] = _Reader["StartWork"].ToString();
            }
            _Reader.Close();
        }
        _EndStored = DateTime.Now.Ticks;
        _StoredTime = TimeSpan.FromTicks(_EndStored - _StartStored);
        Console.WriteLine("Total execution time: " + _StoredTime.ToString());

我很想缩短那段代码,但是……不行:D

TL;DR - 相同查询的 2000 个存储过程只快了大约 4 秒,这对我来说似乎很低?

我使用的存储过程错了吗?

【问题讨论】:

  • 这取决于整个过程需要多长时间。如果第一个用了 5s,第二个用了 1s,那我会说这是一个很大的进步!
  • 我知道这是测试代码,但SqlDataReaderSqlConnectionSqlCommand 都实现了IDisposable,应该在某个时候被处理掉。
  • 测试过程大约需要 30 秒,但最终应用程序将执行大约 10.000 次此类查询

标签: c# sql stored-procedures


【解决方案1】:

大部分开销将是设置存储过程调用和检索结果——在您的示例中执行了 2,000 次。

您可能需要考虑将循环移动到存储过程中,然后调用存储过程一次并一次性获取所有结果。

【讨论】:

  • 具体来说,网络延迟会是瓶颈,除了做一次外,你无能为力。
  • @ck - 我完全同意网络延迟是这里的问题,但我在我们的网络中发现与服务器别名 (svrname) 建立连接比完全限定名称 (svrname.网络)。对于具有数千个连接的循环,效果是巨大的。所以,有些事情你可以尝试。 :)
【解决方案2】:

我同意杰里米的观点。使用存储过程的一个更好的原因是避免在循环中调用数据库的次数不可预测的情况。您应该将循环移动到存储过程本身并调用它一次。因此,您的示例显示存储过程的使用不当。有点像拖拉机和法拉利在犁过的土地上比赛,然后声称法拉利很慢。

【讨论】:

  • 好的,说得好。我也是这么想的,但在那种情况下,创建一个“视图”并查询它不是更容易吗? (使用 MSSQL-Server)
  • 很有可能。这实际上取决于逻辑、查询计划等的复杂性。
  • 这不是第一个答案,但我确实喜欢法拉利/拖拉机的类比。 :)
【解决方案3】:

在新版本的 SQL Server 中,SP 代码和普通代码之间的差异非常非常小,SQL Server 优化了任何查询的执行,特别是在命令没有改变的情况下。

【讨论】:

    【解决方案4】:

    一次BIG到数据库的旅行几乎总是比在循环中完成的相同旅行更快。

    如果你在数据库本身做tyhe循环,你会大大提高性能。

    【讨论】:

      【解决方案5】:
      【解决方案6】:

      您应该始终使用参数化查询,因此您可能根本看不到任何速度差异。

      【讨论】:

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