Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 检索主/详细(嵌套)数据的最有效方法_Sql Server_Performance - Fatal编程技术网

Sql server 检索主/详细(嵌套)数据的最有效方法

Sql server 检索主/详细(嵌套)数据的最有效方法,sql-server,performance,Sql Server,Performance,我的问题在某种程度上是对这一问题的后续:。然而,我想概括一下,并可能会更新它,因为它已经6年了,可能会有新的更好的选择 我在MS SQL Server数据库中有一个典型的主/详细关系,尽管我相信DB不可知的答案可以帮助任何人,因为这是一个非常普遍的问题 MasterTable有MasterId键,然后是附加的master级别字段。 DetailTable有一个DetailId键、一个MasterId外键,然后是其他详细级别字段。 我正在寻找从数据库读取数据并将内存中的嵌套结构加载到数据对象中的最

我的问题在某种程度上是对这一问题的后续:。然而,我想概括一下,并可能会更新它,因为它已经6年了,可能会有新的更好的选择

我在MS SQL Server数据库中有一个典型的主/详细关系,尽管我相信DB不可知的答案可以帮助任何人,因为这是一个非常普遍的问题

MasterTable有MasterId键,然后是附加的master级别字段。 DetailTable有一个DetailId键、一个MasterId外键,然后是其他详细级别字段。 我正在寻找从数据库读取数据并将内存中的嵌套结构加载到数据对象中的最佳方法。我意识到答案可能是它取决于,在这种情况下,它取决于什么

以下是我提出的备选方案:

经典SQL完整查询-我指的是以下几行: 选择* 来自MasterTable 在MasterTable.Id=DetailTable.MasterId上联接DetailTable

[若我并没有弄错的话,这就是ORMs在执行等效数据模型对象的快速加载时将创建的内容……例如,使用.Include in Entity Framework]

这种方法的缺点是数据重复,这是由于必须扁平化这种层次结构,为每个DetailTable记录重复所有需要的MasterTable字段。根据结果集的总大小和MasterTable中所需字段的总大小,这可能会在数据库本身以及之后在将所有数据传输到进程中时产生糟糕的性能。。。另外,我也不确定最终的数据对象具体化是否更快

SQL对XML的完整查询-至少在SQL Server中,我的意思是: 选择主表。*, 从DetailTable中选择* 其中MasterTable.Id=XML路径“Detail”的DetailTable.MasterId,键入 来自XML路径“Master”的MasterTable

我不完全确定SQL Server在幕后做了什么,但输出是分层的,因此,没有数据重复,尽管我想XML格式化过程会有一些成本,XML标记会作为附加数据。然后是将XML结果反序列化到数据对象的附加步骤,但无论是在CPU方面还是在代码行方面,这都不是非常昂贵的,因为它通常已经内置在大多数编程框架中

根据我的经验,这种方法比第一种方法给出了更好的结果,并且随着连接表的数量、结果集的大小等的增加,差异也会增加。。。增加

每个表的SQL查询和内存中的联接—我指的是发送两个不同查询的行: 从MasterTable中选择*,然后 从DetailTable中选择*

然后在内存中执行数据对象层次物化。这可以有效地完成,正如在原始链接中作为答案提供的那样,每个结果集通过一次:

查询按MasterId排序的所有母版,然后查询也按MasterId排序的所有详细信息。然后,使用两个嵌套循环,迭代主数据并为主循环中的每一行创建一个新的主对象,并在细节与当前主对象具有相同的MasterId时迭代细节,并在嵌套循环中填充其_details集合

这需要对每个需要的附加详细信息表进行2次查询或N次查询,但结果集的总大小以及传输到调用进程的内容尽可能小

直到最近,我还没有意识到SQL Server的XML功能,在10个场景中有9个场景中,我发现选项3总是比我很少使用的1好得多,真的。。。但现在我对现实世界中涉及大量数据的场景中的选项2感到好奇,因此我将在我需要的下一个项目中进行一些快速比较

您对FOR XML有什么看法/经验,对于这些备选方案,您一般有什么看法,还有其他建议吗


提前感谢。

不知道,但我认为数据库连接应该足够智能,以便透明地执行重复数据消除。对于像m1、d1、m1、d2、m1、d3……这样的数据来说,这听起来非常琐碎。网络速度是您设置中的一个限制因素吗?我将把工作放在提高网络速度上,而不是重新设计应用程序/查询。重复的主数据应该能够很好地压缩,因此添加网络压缩可能是最简单的解决方案。