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

Fastest way to fetch complex data with many-to-many relationships?

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

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


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

天真的做法

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

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

XML 方法

通过让SQL Server生成XML,我们可以将结构化数据传递给客户端。

它可能看起来像这样:

<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>

我喜欢这种方法,但速度很慢。随着行数的增加,关系变得更加复杂,XMLSQL Server 上的序列化变得缓慢 。有没有办法以某种方式在 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. 在您的应用程序中反序列化

ad 1) 性能影响:~85%

让 SQL 服务器完成艰巨的工作...假设设计良好的结构和合适的索引,将没有更快的方法来获取您的数据。 SQL 服务器具有强大的能力,可以找到 "most bestest" 加入的方式,以完全按照您需要的方式过滤和聚合数据。不会有更好的办法。如果您的数据有大量未更改的可预加载 tables,您可以使用 "load-on-start".

来加快速度

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

ad 2) 性能影响:~4%

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

ad 3) 性能影响:~1%

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

ad 4) 性能影响:~10%

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

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

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

设施

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

最后但同样重要的是,这种方法很容易集成到面向服务的体系结构中...