。net慢的SqlDataReader

问题描述 投票:0回答:2

我正在使用WPF应用程序,该应用程序在SQL Server中执行存储过程。方法Search查询表并产生结果查询,该查询具有1000多个行,并且对象类型为Cliente

查询执行时间为19秒,创建Cliente需花费几秒钟。

对象的创建以54,59,58,59,65的块为准

我期望查询会花费一些时间,但是对于创建对象而言不会:

public IEnumerable<Cliente> Search(Filtro filtro)
{
        System.Diagnostics.Stopwatch stop = new System.Diagnostics.Stopwatch();
        stop.Start();

        System.Diagnostics.Debug.WriteLine(stop.Elapsed);

        using (var q = SqlHelper.ExecuteReader("MyConection", "MySP", params))
        {
            System.Diagnostics.Debug.WriteLine(stop.Elapsed);
            List<Cliente> clientes = new List<Cliente>();

            while (q.Read())
            {
                clientes.Add(new Cliente()
                {
                    Id = q.GetInt32(q.GetOrdinal("ID")),
                    Field1= q.GetString(q.GetOrdinal("Field1")),
                    Field2= q.GetString(q.GetOrdinal("Field2")),
                    Field3= q.GetString(q.GetOrdinal("Field3")),
                    Field4= q.GetInt32(q.GetOrdinal("Field4")),
                    Field5= q.GetString(q.GetOrdinal("Field5")),
                    Field6= q.GetString(q.GetOrdinal("Field6")),
                    Field7= q.GetString(q.GetOrdinal("Field7")),
                    Field8= q.GetDateTime(q.GetOrdinal("Field8")),
                    Field9= q.GetInt32(q.GetOrdinal("Field9")),
                    Field10= q.GetString(q.GetOrdinal("Field10")),
                    Field11= q.GetString(q.GetOrdinal("Field11")),
                    Field12= q.GetString(q.GetOrdinal("Field12")),
                    Field13= q.GetDateTime(q.GetOrdinal("Field13")),
                    Field14= q.GetString(q.GetOrdinal("Field14")),
                });

                System.Diagnostics.Debug.WriteLine(stop.Elapsed);
            }

            System.Diagnostics.Debug.WriteLine(stop.Elapsed);
            stop.Stop();

            return clientes;
        }
}

我正在使用System.Diagnostics.Stopwatch记录时间。

00:00:00.0000024 << start method
00:00:19.0196951 << 19 seconds later query ends
00:00:19.0216880 << start create object Cliente
00:00:19.0226029
......
00:00:19.0430857
00:00:19.0443222
00:00:19.0447338 << here .net stop
00:00:37.6781235 << 18 seconds later start again to create object Client
00:00:37.6809429
00:00:37.6830919
...
00:00:37.7094000
00:00:37.7097978
00:00:37.7102040 << here .net framework stop
00:00:56.0205271 << 19 seconds later start again create object Client
00:00:56.0238062
00:00:56.0266515
....
00:00:56.0702602
00:00:56.0706580
00:00:56.0710598 << here .net framework stop
00:01:14.8534896 << 18 seconds later start again create object Client
00:01:14.8566631
00:01:14.8595772
....
00:01:14.8945812
00:01:14.8958162 << here .net framework stop
00:01:33.2787788 << 19 seconds later start again create object Client
00:01:33.2801869
....
00:01:34.6647856 << end

为什么对象要分块创建然后停止?

如何优化代码,或者我缺少关于SqlDataReader的内容?

c# .net sql-server sqldatareader
2个回答
0
投票

可能杀死您的是每次在每个字段,每个记录上都调用GetOrdinal。您可能会通过使用阅读器,获取架构并在列表中获得顺序位置ONCE来获得提升,然后在添加时仅使用该值。像下面这样。读者将获得序数结果。

using (var q = SqlHelper.ExecuteReader("MyConection", "MySP", params))
{
    System.Diagnostics.Debug.WriteLine(stop.Elapsed);
    List<Cliente> clientes = new List<Cliente>();


    // Build your own list in the same order you are reading them in
    List<int> myOrdinal = new List<int>();
    myOrdinal.Add(q.GetOrdinal("ID"));
    myOrdinal.Add(q.GetOrdinal("Field1"));
    myOrdinal.Add(q.GetOrdinal("Field2"));
    myOrdinal.Add(q.GetOrdinal("Field3"));
    myOrdinal.Add(q.GetOrdinal("Field4"));
    myOrdinal.Add(q.GetOrdinal("Field5"));
    myOrdinal.Add(q.GetOrdinal("Field6"));
    myOrdinal.Add(q.GetOrdinal("Field7"));
    myOrdinal.Add(q.GetOrdinal("Field8"));
    myOrdinal.Add(q.GetOrdinal("Field9"));
    myOrdinal.Add(q.GetOrdinal("Field10"));
    myOrdinal.Add(q.GetOrdinal("Field11"));
    myOrdinal.Add(q.GetOrdinal("Field12"));
    myOrdinal.Add(q.GetOrdinal("Field13"));
    myOrdinal.Add(q.GetOrdinal("Field14"));

    while (q.Read())
    {
        clientes.Add(new Cliente()
        {
            // then use your list of ordinal values directly
            Id = q.GetInt32(myOrdinal[0]),
            Field1 = q.GetString(myOrdinal[1]),
            Field2 = q.GetString(myOrdinal[2]),
            Field3 = q.GetString(myOrdinal[3]),
            Field4 = q.GetInt32(myOrdinal[4]),
            Field5 = q.GetString(myOrdinal[5]),
            Field6 = q.GetString(myOrdinal[6]),
            Field7 = q.GetString(myOrdinal[7]),
            Field8 = q.GetDateTime(myOrdinal[8]),
            Field9 = q.GetInt32(myOrdinal[9]),
            Field10 = q.GetString(myOrdinal[10]),
            Field11 = q.GetString(myOrdinal[11]),
            Field12 = q.GetString(myOrdinal[12]),
            Field13 = q.GetDateTime(myOrdinal[13]),
            Field14 = q.GetString(myOrdinal[14]),

        });
        System.Diagnostics.Debug.WriteLine(stop.Elapsed);
    }
    System.Diagnostics.Debug.WriteLine(stop.Elapsed);
    stop.Stop();
    return clientes;
}

如果这行得通,那么知道您的性能改进结果会很有趣。


-2
投票

要在数据库中读取和发布sql查询,可以使用Dapper ORM。使用dapper是对数据库进行CRUD操作的一种更快,更简单的方法。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.