Questions tagged «table-valued-parameters»

5
如何通过.net代码将表值参数传递给存储过程
我有一个SQL Server 2005数据库。在一些过程中,我有一些表参数,这些参数以nvarchar(用逗号分隔)传递给存储的proc,并在内部划分为单个值。我将其添加到SQL命令参数列表中,如下所示: cmd.Parameters.Add("@Logins", SqlDbType.NVarchar).Value = "jim18,jenny1975,cosmo"; 我必须将数据库迁移到SQL Server2008。我知道有表值参数,并且知道如何在存储过程中使用它们。但是我不知道如何在SQL命令中将其传递给参数列表。 有人知道该Parameters.Add过程的正确语法吗?还是有另一种方式传递此参数?

4
bcp / BULK INSERT与表值参数的性能
BULK INSERT由于架构已更改,我将不得不使用SQL Server的命令重写一些相当旧的代码,我想到也许我应该考虑改用TVP切换到存储过程,但是我想知道会有什么效果它可能会影响性能。 一些背景信息可能有助于解释为什么我问这个问题: 数据实际上是通过Web服务输入的。该Web服务将文本文件写入数据库服务器上的共享文件夹,该文件夹随后执行BULK INSERT。此过程最初是在SQL Server 2000上实现的,当时实际上除了INSERT在服务器上删除几百条语句外,别无选择,这实际上是原始过程,并且会造成性能灾难。 数据被批量插入到永久登台表中,然后合并到更大的表中(此后将从登台表中删除)。 要插入的数据量是“大”的,而不是“巨大的”-通常只有几百行,在极少数情况下可能是5-10k行。因此,我的直觉是,BULK INSERT作为一个未记录的操作不会有太大的不同(但我当然不确定,因此是问题)。 插入实际上是更大的流水线批处理过程的一部分,需要连续多次进行。因此性能是至关重要的。 我想将其替换BULK INSERT为TVP的原因是: 通过NetBIOS编写文本文件可能已经花费了一些时间,并且从体系结构的角度来看这是非常可怕的。 我认为可以(并且应该)取消登台表。造成这种情况的主要原因是,插入的数据需要在插入的同时用于其他两次更新,而尝试从大量生产表进行更新要比使用几乎为空的登台要昂贵得多表。对于TVP,参数基本上是临时表,我可以在主插入之前/之后使用它进行任何操作。 我几乎可以消除重复检查,清理代码以及与批量插入相关的所有开销。 如果服务器一次获得一些事务,则无需担心登台表或tempdb上的锁争用(我们尝试避免这种情况,但它确实发生了)。 显然,在将任何产品投入生产之前,我将对此进行概要分析,但是我认为在我度过所有时间之前先询问一下是一个好主意,看看是否有人为此发布使用TVP的严厉警告。 所以-对于任何对SQL Server 2008足够熟悉的人尝试过或至少对此进行过调查,那么结论是什么?对于插入(例如几百到几千行)的情况,TVP是否会切芥菜?与散装刀片相比,性能有显着差异吗? 更新:现在问号减少了92%! (又称:测试结果) 经过36阶段的部署过程之后,最终结果现已投入生产。两种解决方案都经过了广泛的测试: 提取共享文件夹代码并SqlBulkCopy直接使用该类; 使用TVP切换到存储过程。 以便读者可以了解到底经过了什么测试,以消除对这些数据的可靠性的任何疑问,这是对该导入过程实际作用的更详细说明: 从通常约20至50个数据点的时间数据序列开始(尽管有时可能会增加几百个)。 对其进行大量疯狂的处理,这些处理基本上独立于数据库。此过程是并行的,因此(1)中大约8-10个序列被同时处理。每个并行过程会生成3个附加序列。 取所有3个序列和原始序列,并将它们合并为一批。 将现在完成的所有8-10个处理任务中的批次合并为一个大的超级批次。 使用BULK INSERT策略(请参阅下一步)或TVP策略(跳至步骤8)导入它。 使用SqlBulkCopy该类将整个超级批处理转储到4个永久登台表中。 运行一个存储过程,该存储过程是(a)在两个表上执行一系列聚合步骤,包括几个JOIN条件,然后(b)MERGE在6个生产表上使用聚合和非聚合数据执行a 。(完成) 要么 生成4个DataTable对象,其中包含要合并的数据;其中3个包含CLR类型,但不幸的是ADO.NET TVP没有正确地支持它们,因此必须将它们作为字符串表示形式使用,这会严重影响性能。 将TVP馈送到存储过程,该过程基本上与(7)相同,但直接与接收到的表一起进行。(完成) 结果相当接近,但是TVP方法最终平均表现更好,即使数据超过1000行少量。 请注意,此导入过程连续运行了数千次,因此仅通过计算完成所有合并所花费的小时数(是,小时),就很容易获得平均时间。 最初,平均合并几乎要花8秒钟才能完成(在正常负载下)。消除NetBIOS的麻烦并切换为SqlBulkCopy将时间减少到几乎恰好7秒。切换到TVP可以将时间进一步减少到每批5.2秒。对于运行时间以小时为单位的过程,这将使吞吐量提高35% -一点也不差。与相比,也提高了约25%SqlBulkCopy。 实际上,我相当有信心,真正的进步远不止于此。在测试过程中,很明显,最终的合并不再是关键的路径。相反,进行所有数据处理的Web服务开始受到输入请求数量的限制。CPU和数据库I / O都没有真正达到极限,并且没有明显的锁定活动。在某些情况下,我们发现连续合并之间存在几秒钟的空闲间隔。使用时有一点缝隙,但要小得多(半秒左右)SqlBulkCopy。但是我想那将成为另一天的故事。 结论:表值参数确实比BULK INSERT在中型数据集上执行复杂的导入+转换过程的操作要好。 …
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.