sql - 获取具有多对多关系的复杂数据的最快方法?

标签 sql sql-server xml dto

正在运行SQL Server 2014。我有多个表,与其他表具有多对多关系。很多时候,我需要从表 A 中获取 N 行,同时显示项目表 BC。我想尽可能高效地做到这一点。

最有效的方法是什么?下面是一些想法。


注意:客户端和服务器不一定位于同一网络。

天真的方法

天真的方法看起来像这样:

  • 客户端向服务器请求表 A 中的 N 行并对它们进行反序列化。
  • 对于 A 中的每个项目,客户端随后向服务器询问 B 中与其相关的项目。
  • 对于 A 中的每个项目,客户端会向服务器询问 C 中与其相关的项目。

这会导致大量的数据库往返,在慢速网络(即WAN)上时会导致严重的性能问题。这根本不是一个选择。

XML 方法

通过让 SQL Server 生成 XML,我们可以向客户端提供结构化数据。

  • 客户端向服务器请求表 A 中 N 行的 XML,其中每行包含 BC。然后,XML 将被反序列化为 C# 中的现成对象。

它可能看起来像这样:

<data>
  <a_collection>
    <a>
      <id>1</id>
      <title>A Title<title>
      <b_collection>
        <b>
          <id>123</id>
          <description>B stuff here</description>
        </b>
        <b>
          <id>124</id>
          <description>Other B stuff here</description>
        </b>
      </b_collection>
      <c_collection />
    </a>
  </a_collection>
</data>

我喜欢这种方法,但速度很慢。随着行数的增加以及关系变得更加复杂,SQL Server 上的 XML 序列化变得缓慢。有没有办法在 CPU 和 RAM 使用方面以某种方式改进 XML 序列化?

JSON 方法

SQL Server 2016发布时,我们将可以选择使用JSON而不是XML。也许上面的 XML 方法可以转换为 JSON 并可能受益于更快的序列化器?但是,当您无法再从 System.Xml.Serialization 中受益时,如何反序列化对象呢?

WCF 方法

在客户端和数据库服务器之间创建一个额外的层似乎是个好主意。这样的解决方案与 XML 方法相比如何?

其他方法?

应该有其他有效的方法将结构化数据从 SQL Server 传递到客户端。

最佳答案

在您的情况下,XML 方法是我的...

编辑:我认为最好考虑四个不同的问题:

  1. 获取数据(连接、过滤、聚合)
  2. 准备数据(XML、JSON 等)
  3. 传输您的数据(字节大小)
  4. 在应用程序中反序列化

广告 1) 性能影响:~85%

让 SQL Server 来完成这项艰巨的工作...假设结构设计良好并且索引合适,那么就没有比这更快的方法来获取数据了。 SQL Server 具有巨大的能力,可以找到“最佳”的方式来连接、过滤并按照您需要的方式聚合数据。不会有更好的办法了。如果您的数据有大量可预加载且不更改的表,您可以通过“启动时加载”来加快速度。

我会使用参数化表值内联(!!!) UDF。它们在维护和性能方面是最好的,您可以轻松地将您的需求分解为模块化部分。

ad 2) 性能影响:~4%

我会对 1) 中的 UDF 执行额外的 SELECT ... FOR XML PATH() 操作。使用FOR XML PATH,您可以完全控制给定的 XML。您稍后可以轻松地将其更改为 JSON 方法。您可能会想到自己的格式(某种 csv?),但我不会...

ad 3) 性能影响:~1%

传输的数据将尽可能接近最小。自己的格式将是最小的,但 JSON 足够小,XML 也没有那么大......我不认为,你真的需要太担心字节大小...... XML 是最强大的(添加通过属性的元数据)。

广告 4) 性能影响:~10%

在 C# 中,您可以大力支持将数据转换为可查询的结构。一种非常简单的方法是 DataSet.ReadXml

另一个简单的方法是 XmlDocument.LoadXml

使用 pe 定义的结构,您可以将 XML 直接反序列化为用户定义的类...

事实

AFAIC 是唯一相关的点(No 1)。在任何情况下,传输的数据都是完全相同的,或多或少有一些字节开销...即使没有显式序列化,也会有一些隐式序列化和反序列化,以便将数据发送到应用程序。性能差异并不重要......

最后但并非最不重要的一点是,这种方法很容易集成到面向服务的架构中......

关于sql - 获取具有多对多关系的复杂数据的最快方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34432867/

相关文章:

sql - 如何根据时间段复制数据记录?

用于复杂/大型 XML 的 Java Stax

java - 如何在Java中为带有属性的自包含标签编写xml注释

android - 以编程方式添加布局android

asp.net - 将自动增量插入数据库 ASP.net

sql - 如何仅在连续行上应用聚合函数?

sql-server - SQL Server 包含未返回预期结果的全文函数

php - mssql_connect() : Unable to connect to server (without freetds. session )

mysql - 简单的 PIVOT 查询抛出错误消息

如果另一张表上不存在特定行,则MySQL有条件地插入到一张表中