正在运行SQL Server 2014
。我有多个表与其他表有多对多的关系。很多时候,我需要从表A
中获取N行,同时还显示项目表B
和C
。我希望尽可能高效地完成这项工作。
最有效的方法是什么?以下一些想法。
注意:客户端和服务器不一定在同一网络上。
天真的方法看起来像这样:
A
中的N行并对其进行反序列化。A
中的每个项目,客户端会向服务器询问B
中的相关项目。A
中的每个项目,客户端会向服务器询问C
中的相关项目。这会导致疯狂的数据库往返次数,在慢速网络(即WAN
)上导致严重的性能问题。它根本不是一种选择。
通过让SQL Server
生成XML
,我们可以向客户提供结构化数据。
XML
中的N行A
,其中每行包含来自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>
我喜欢这种方法,但速度很慢。随着行数的增加以及关系变得更加复杂,XML
上的 SQL Server
序列化变得缓慢。有没有办法在CPU和RAM使用方面以某种方式改进XML
序列化?
发布SQL Server 2016
后,我们可以选择使用JSON
代替XML
。也许上面的XML
方法可以转换为JSON
并可能从更快的序列化程序中受益?但是,当您无法再从System.Xml.Serialization
中受益时,如何对对象进行反序列化?
在客户端和数据库服务器之间创建一个额外的层似乎是一个好主意。这种解决方案与XML
方法相比如何?
应该有其他有效的方法将结构化数据从SQL Server
传递给客户。
答案 0 :(得分:2)
在您的情况下,XML方法是我的......
编辑:我认为最好考虑四个不同的问题:
ad 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是最强大的(添加元数据通过attributs)。
ad 4)效果影响:~10%
在C#中,您可以获得将数据转换为可查询结构的强大支持。一个非常简单的方法是DataSet.ReadXml
另一种简单的方法是XmlDocument.LoadXml
使用pe定义的结构,您可以将XML直接反序列化为用户定义的类......
<强> FACIT 强>
AFAIC是No 1)的唯一相关点。在任何情况下传输的数据都是相同的,一些字节开销或多或少......即使没有显式序列化,也会有一些隐式序列化和反序列化,以便将数据发送到应用程序。性能差异并不重要......
最后但并非最不重要的是,这种方法很容易集成到面向服务的架构中......