我有桌子,里面有超过7000万条记录;我刚刚发现开发人员在批量插入之前丢弃索引,然后在批量插入结束后再次创建。存储过程的执行时间接近30分钟(执行drop index,批量插入,然后从头开始重新创建索引
建议:这是一个很好的做法,可以从拥有超过70多万条记录的表中删除INDEX,每天增加3-4百万。
通过在批量插入之前不丢弃索引来提高性能会不会有帮助?
在BIG TABLE中进行BULK插入时,遵循的最佳做法是什么。
谢谢和问候
答案 0 :(得分:7)
与SQL Server中的所有内容一样,“它取决于”
在插入期间维护索引会产生开销,并且在插入后重建索引会产生开销。确定哪种方法产生较少开销的唯一方法是尝试它们并对它们进行基准测试。
如果我是一个博彩人,我会放下我的赌注,即将指数留在原地将完全重建,但我没有完整的图片来做出有根据的猜测。同样,唯一可以确定的方法是尝试这两种选择。
一个关键优化是确保批量插入符合群集密钥顺序。
如果我正确地阅读了你的问题,那个表在加载期间几乎没有限制(锁定),这是一个问题。
如果您的主要目标是提高可用性/减少阻止,请尝试采用A / B表方法。
A / B方法细分如下:
给定一个名为“MyTable”的表,你实际上有两个物理表(MyTable_A和MyTable_B)和一个视图(MyTable)。
如果MyTable_A包含当前“活动”数据集,则您的视图(MyTable)将从MyTable_A中选择所有列。同时,您可以在MyTable_B上进行全权委托(其中包含MyTable_A数据的副本和您正在编写的新数据。)一旦MyTable_B被加载,编入索引并准备就绪,请更新您的“MyTable”视图以指向MyTable_B并截断MyTable_A 。
这种方法假设您愿意增加I / O和存储成本(在您的情况下显着)以保持可用性。它还假设您的大表也相对静态。如果您确实遵循这种方法,我建议使用第二个视图,例如MyTable_old,它指向非实时表(即,如果MyTable_A是当前的表示表并且由MyTable视图引用,MyTable_old将引用MyTable_B)您将更新更新MyTable视图的同时MyTable_old视图。
根据您要插入的数据的性质(以及您的SQL Server版本/版本),您也可以利用分区(MSDN blog on this topic.)