解析一些数据并将其插入.NET的3个表中。使用表值参数传递数据,因为某些插入是600,000行。传递对象(不是DataTables),它们通过引用传递(TVP的性质)。获得100:1的直接值插入增益,因为插入值一次限制为1000行。在存储过程中,从TVP到实际表的插入按聚簇索引排序。这些表没有聚簇索引以外的索引。 SP采用TABLOCK,因为这些是一次写入表和一个数据加载器。填充因子100.数据或事务日志大小没有增加 - 它的大小适合总数据负载。最后到了问题。在过去的4个小时里已经插入了2亿行。插入响应时间下降了1/2。如果填充因子是100并且我按照聚集索引进行排序,那么为什么响应下降呢?我能做些什么来解决这个问题?
直到我使用它才得到TVP - 它就像一个反向DataReader。
我要感谢您的帮助,并为不正确的问题陈述道歉。对于每个解析(在这种情况下,我正在解析200,000),插入按聚集索引排序。但是,对于3个表中只有1个是聚簇索引顺序中的下一个解析。解析70,000后,好表的扫描密度为99%,但其他两个表严重碎片,扫描密度为12%。
在两个碎片表上设置填充因子50并重新编制索引。现在我的最大速度提高了1/3。我只需要停止这个过程并每隔几个小时重新索引一次。
我最终做的是更改聚簇索引以匹配插入顺序。曾经是集群的创建了一个独特的索引。我禁用唯一的索引插入数据,然后重建唯一索引。在这种情况下,我在10小时的跑步中获得了300:1的表现。这不是额外的0 - 三百比一。这不是捏造 - 相比于从有序索引开始和填充因子或30.与额外索引相比,我的表格大小更小,因为我可以将两个填充因子都设置为100。
我在某些查询中使用了#temp,因此我可以按照查询只知道的顺序获取行。我将#temp转换为TVP并获得了1/2秒(大约需要创建和删除#temp的时间)。
答案 0 :(得分:0)
每个OP转换评论以回答......
除了@SqlACID提及的自动统计信息之外,随着表填满,约束检查可能会变得更加昂贵。如果我要认真加载一个表,我通常会计划禁用或删除索引和约束,并在之后重新创建它们,如果速度是我的最终目标。如果违反约束,这可能意味着在事后删除行,或者在可能的情况下预先对批量数据进行更好的验证。