我正在使用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
的内容?
可能杀死您的是每次在每个字段,每个记录上都调用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;
}
如果这行得通,那么知道您的性能改进结果会很有趣。
要在数据库中读取和发布sql查询,可以使用Dapper ORM。使用dapper是对数据库进行CRUD操作的一种更快,更简单的方法。