将表传递给存储过程
我有一个有200亿行的表。表格没有任何索引,因为它是在执行批量插入操作时动态创建的。该表在存储过程中,其执行以下操作将表传递给存储过程
Delete A
from master a
inner join (Select distinct Col from TableB) b
on A.Col = B.Col
Insert into master
Select *
from tableB
group by col1,col2,col3
TableB
被使用是有20个十亿行的一个。我不想直接执行SP,因为它可能需要几天才能完成执行。 Master
也是一个巨大的表,并聚集在Col
- 我可以通过行存储过程的块并进行operation.This可能会减少日志文件的增长指数。如果是的我怎么能这样做
- 我应该在表上创建聚集索引,并执行SP可能会快一点,但我认为在一个巨大的表上创建CI可能需要10个小时才能完成。
或者是有什么办法来执行此操作快捷
我用类似this one的方法。如果可以的话,我建议将数据库放入批量记录恢复模式而不是完全恢复模式。
博客条目转载以下未来证明它。
以下是用于将大量记录从一个表格转移到另一个表格的技术。由于几个原因,这个比例非常好。 首先,在提交 交易之前,这不会填满整个日志。相反,它将以10,000 记录的块形式填充表格。其次,通常要快得多。您将必须在批量大小周围玩 。根据系统的不同,有时它在10,000, 有时会更高效500,000。
如果您不需要插入到现有表格中,只需要表格的 副本,最好是执行
SELECT INTO
。但是,对于此示例,我们将插入现有的表中。您应该做的另一个诀窍是将 数据库的恢复模式更改为简单。这样, 事务日志中的日志记录就会少得多。
下面仅将
WITH (TABLOCK)
工作在SQL 2008DECLARE @BatchSize INT = 10000 WHILE 1 = 1 BEGIN INSERT INTO [dbo].[Destination] --WITH (TABLOCK) -- Uncomment for 2008 ( FirstName ,LastName ,EmailAddress ,PhoneNumber ) SELECT TOP(@BatchSize) s.FirstName ,s.LastName ,s.EmailAddress ,s.PhoneNumber FROM [dbo].[SOURCE] s WHERE NOT EXISTS ( SELECT 1 FROM dbo.Destination WHERE PersonID = s.PersonID ) IF @@ROWCOUNT < @BatchSize BREAK END
采用上述例子,它具有至少一个非 群集上
PersonID
两个表中指数是重要的。转移记录的另一种方式是使用多个线程。指定 的记录范围为这样:
INSERT INTO [dbo].[Destination] ( FirstName ,LastName ,EmailAddress ,PhoneNumber ) SELECT TOP(@BatchSize) s.FirstName ,s.LastName ,s.EmailAddress ,s.PhoneNumber FROM [dbo].[SOURCE] s WHERE PersonID BETWEEN 1 AND 5000 GO INSERT INTO [dbo].[Destination] ( FirstName ,LastName ,EmailAddress ,PhoneNumber ) SELECT TOP(@BatchSize) s.FirstName ,s.LastName ,s.EmailAddress ,s.PhoneNumber FROM [dbo].[SOURCE] s WHERE PersonID BETWEEN 5001 AND 10000
于超快速的性能但是,我建议使用SSIS。 特别是在SQL Server 2008中。我们最近在5分钟内转移了1700万个 记录,并在同一台服务器上执行了一个SSIS包,作为其在两个数据库之间传输的两个数据库。
SQL Server 2008在插入记录时,SQL Server 2008对其日志记录机制进行了更改。以前,要执行最小化记录的插入 ,您必须执行
SELECT.. INTO
。 现在,如果您可以锁定要插入的 表,则可以执行最低限度记录的插入。下面的例子显示了 这个例子。此规则的例外情况是,如果您有 表上的聚集索引,并且该表不是空的。如果表为空,并且您获取表锁,并且您有一个聚集索引,则最小日志记录为 。但是,如果表格中有数据,则会记录插入 。现在,如果您在堆上有非聚簇索引,并且您获得了表锁,那么只记录非聚簇索引 。在插入 记录之前删除索引总是更好。要确定登录就可以使用下面的语句
SELECT * FROM ::fn_dblog(NULL, NULL)
信贷以上的去德里克·迪特尔在SQL Server的行星数量。
如果您已将表格传递给您的存储过程,you can pass a table-valued parameter to a stored procedure in SQL Server 2008。建议使用其他方法,比如分区,可能会更好。在具有200亿行的表格上选择不同可能是问题的一部分。我想知道是否一些非常基本的调整也不会有帮助:
Delete A
from master a
where exists (select 1 from TableB b where b.Col = a.Col)
如果你正在做插入操作,索引会减慢你的速度。在运行插入之前,删除主文件夹上的所有索引。 – paqogomez
我不能在'master'表中删除'索引',因为它包含了近500亿行的历史数据。 – praveen
您可以执行删除操作,删除索引并执行插入操作,然后重新创建索引。根据索引的数量,这将比插入而不移除要快得多。此外,删除的这个子选项毫无价值,会降低查询速度。直接加入'TableB'并且不要调用不同。 – paqogomez