正在运行SQL Server 2014
。我有多个表,与其他表具有多对多关系。很多时候,我需要从表 A
中获取 N 行,同时显示项目表 B
和 C
。我想尽可能高效地做到这一点。
最有效的方法是什么?下面是一些想法。
注意:客户端和服务器不一定位于同一网络。
天真的方法
天真的方法看起来像这样:
- 客户端向服务器请求表
A
中的 N 行并对它们进行反序列化。 - 对于
A
中的每个项目,客户端随后向服务器询问B
中与其相关的项目。 - 对于
A
中的每个项目,客户端会向服务器询问C
中与其相关的项目。
这会导致大量的数据库往返,在慢速网络(即WAN
)上时会导致严重的性能问题。这根本不是一个选择。
XML 方法
通过让 SQL Server
生成 XML
,我们可以向客户端提供结构化数据。
- 客户端向服务器请求表
A
中 N 行的XML
,其中每行包含B
和C
。然后,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 方法是我的...
编辑:我认为最好考虑四个不同的问题:
- 获取数据(连接、过滤、聚合)
- 准备数据(XML、JSON 等)
- 传输您的数据(字节大小)
- 在应用程序中反序列化
广告 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/