2017-06-19 90 views
1

第一个问题在这里:)WCF服务查询时间与直接查询到DB 6X慢

我与得到的查询从一个WinForms应用程序,将其转换为XML,将其发送到SQL Server数据库WCF服务工作,将查询数据作为XML返回,将其转换为DataTable并将其发送回WinForms应用程序。

我测试了这个和直接的数据库查询之间的速度差异,看起来使用我的服务减慢了6倍。

我需要做的是减少服务执行查询的时间,但我不知道它是如何工作的。 关于问题出在哪里,你有什么大概的想法吗?有什么方法可以提高服务的性能吗?使用JSON(而不是XML)可以帮助解决这个问题吗?

非常感谢您阅读本文,期待着您的解答!

这里是我用来测试两个连接代码:

namespace TestServiceVSDatabaseSpeed 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // Initialization 
      DataTable dtService = new DataTable(), dtDirect = new DataTable(); 
      Console.Write("~Direct Connection VS Service Connection~\n\nSELECT * FROM COILS\n"); 
      Stopwatch sw1 = new Stopwatch(), sw2 = new Stopwatch(); 

      // Direct connection test 
      sw1.Start(); 
      dtDirect = GetSqlDataDirectConnection(); 
      Single directTime = sw1.ElapsedMilliseconds; 
      Console.WriteLine("Direct query time: {0} ms ({1} rows)", directTime, dtDirect.Rows.Count); 
      sw1.Stop(); 

      // Service connection test 
      sw2.Start(); 
      dtService = GetSqlDataServiceConnection(); 
      Single serviceTime = sw2.ElapsedMilliseconds; 
      Console.WriteLine("Query via service time: {0} ms ({1} rows)", serviceTime, dtService.Rows.Count); 
      sw2.Stop(); 

      // Conclusion 
      Console.WriteLine("\nDirect Connection faster than Service Connection by {0} ms!", serviceTime - directTime); 
      Console.WriteLine("That's {0} times faster!", serviceTime/directTime); 
      Console.ReadLine(); 
     } 

     /// <summary> 
     /// Does a direct query to the database 
     /// </summary> 
     /// <returns>A DataTable.</returns> 
     private static DataTable GetSqlDataDirectConnection() 
     { 
      using (SqlConnection conn = new SqlConnection()) 
      { 
       conn.ConnectionString = "Persist Security Info=False;User ID=MyId;Password=MyPassword;Initial Catalog=The_Catalogue;Server=ThisServer"; 

       try 
       { 
        conn.Open(); 
       } 
       catch (Exception e) 
       { 
        Console.WriteLine(e.Message); 
       } 

       using (SqlCommand command = new SqlCommand("SELECT * FROM Coils", conn)) 
       { 
        using (SqlDataAdapter adapter = new SqlDataAdapter(command)) 
        { 

         DataTable coilTable = new DataTable("Coils"); 
         adapter.Fill(coilTable); 

         return coilTable; 
        } 
       } 
      } 
     } 

     /// <summary> 
     /// Does a query to the database via the IOM Service. 
     /// </summary> 
     /// <returns>A DataTable.</returns> 
     private static DataTable GetSqlDataServiceConnection() 
     { 
      DataContractClient contract = new DataContractClient(); 
      contract.Endpoint.Address = new EndpointAddress("net.tcp://localhost:8888/MyService/DataContract"); 
      NetTcpContextBinding netTcpContextBinding = new NetTcpContextBinding(SecurityMode.None) { MaxReceivedMessageSize = 2147483647 }; 
      contract.Endpoint.Binding = netTcpContextBinding; 
      contract.Endpoint.Contract = ContractDescription.GetContract(typeof(IDataContract)); 

      return contract.ExecuteQueryNoParam("SELECT * FROM Coils", Catalog.SqlCatalog).Tables[0]; 
     } 
    } 
} 

下面是结果:

~Direct Connection VS Service Connection~ 

SELECT * FROM COILS 
Direct query time: 436 ms (24596 rows) 
Query via service time: 2748 ms (24596 rows) 

Direct Connection faster than Service Connection by 2312 ms! 
That's 6.302752 times faster! 
+0

除了转换数据的开销之外,这里有相当数量的[DataTables中的固有开销](https://stackoverflow.com/questions/424598/what-is-the-memory-overhead-of-storing- data-in-a-net-datatable),这将全部必须回落。 – stuartd

+0

很多原因......对于 - 可能会考虑net.tcp的二进制编码。检查第一次呼叫与后续呼叫性能......因为服务中可能存在一些初始化成本。服务实例可能会起作用 - 特别是如果您的服务启动缓慢。在服务案例中,数据表被填充,然后序列化,传输,然后反序列化......所有代价都很高。随着尺寸的增加,赌注开销下降(百分比)。 – Clay

+0

使我的皮肤爬行看到通过服务连接发送的SQL语句,顺便说一句。可怕 - 并且紧密耦合...但是再次,使用数据表耦合太紧密。考虑一个数据协定装饰的POCO--它可能会更快地序列化/反序列化。 – Clay

回答

0

如果我看它,它似乎我们需要看到服务转换电话。 要回答您的问题:

  1. 通常,直接调用速度更快是正常的,转换为XML可能需要一些时间。
  2. 不看不到服务本身。
  3. 我不认为改用JSON会有很大的改变,你仍然在处理24596行。

您可以在调用后处理结果。但总而言之,这是正常的,你有一个很大的性能影响,确保使用索引,如果你没有使用它,你可能会遇到更大的问题与查询时间,如果你只选择一些项目。