我将数据从远程数据库提取到本地MS SQL Server数据库,标准是PK是否高于我在数据仓库中的数据,或者编辑日期是否在我提供的参数范围内。这非常快,所以我很满意。但是,当我尝试将此delta表同步到我的数据仓库时,需要很长时间。
这是我的SPROC:
ALTER PROCEDURE [dbo].[sp_Sync_Delta_Table]
@tableName varchar(max)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sql as varchar(4000)
-- Delete rows in MIRROR database where ID exists in the DELTA database
SET @sql = 'Delete from [SERVER-WHS].[MIRROR].[dbo].[' + @tableName
+ '] Where [ID] in (Select [ID] from [SERVER-DELTA].[DELTAS].[dbo].[' + @tableName + '])'
EXEC(@sql)
-- Insert all deltas
SET @sql = 'Insert Into [SERVER-WHS].[MIRROR].[dbo].[' + @tableName
+ '] Select * from [SERVER-DELTA].[DELTAS].[dbo].[' + @tableName + ']'
EXEC(@sql)
END
它有效,但我认为这需要太长时间。例如:将DELTA表中的3590条记录插入到包含3,600,761的MIRROR表中需要25分钟。
任何人都可以告诉我如何在SSMS上轻松完成这项工作吗?我正在使用2008 R2,顺便说一句。
再次感谢!
内特
答案 0 :(得分:2)
问题可能是在3,600,761上进行表扫描以查看新记录是否唯一所需的时间。
首先,让我们确认目标表上的主键(ID)是聚簇索引并且正在增加。
SELECT s.name, o.name, i.name, i.type_desc, ic.key_ordinal, c.name
FROM sys.objects o
JOIN sys.columns c ON (c.object_id = o.object_id)
JOIN sys.schemas s ON (s.schema_id = o.schema_id)
JOIN sys.indexes i ON (i.object_id = o.object_id)
JOIN sys.index_columns ic ON (ic.object_id = i.object_id AND ic.index_id = i.index_id AND ic.column_id = c.column_id)
WHERE o.name = '[table_name]'
如果索引不是升序整数,则插入可能会导致大量页面拆分。
其次,插入的其他对象会影响什么。是否有触发器,物化视图或非聚集索引?
第三,你有吗
我的建议是将镜像服务器上的数据暂存在本地表中。它可以像下面一样简单:
SET @sql = 'SELECT INTO * [MIRROR].[dbo].[' + @tableName + '_Staging] from [SERVER-DELTA].[DELTAS].[dbo].[' + @tableName + ']'
EXEC(@sql)
之后,向表中添加一个聚簇主键。
SET @sql = 'ALTER TABLE [MIRROR].[dbo].[' + @tableName + '_Staging] ADD CONSTRAINT [PK_' + @tableName + '] PRIMARY KEY CLUSTERED (Id ASC)'
EXEC(@sql)
此时,尝试将数据插入真实表中。这次优化器应该会更有帮助。
答案 1 :(得分:1)
将删除部分更改为:
SET @sql = 'Delete tbl1 from [SERVER-WHS].[MIRROR].[dbo].[' + @tableName
+ '] tbl1 inner join [SERVER-DELTA].[DELTAS].[dbo].[' + @tableName + '] tbl2 on tbl1.[ID] = tbl2.[ID]'
将来使用INNER JOIN而不是IN with Sub Query。