Sql 合并复制数据库中的插入速度非常慢
我有一个SQL server,它通过合并复制安装到800个运行SQL CE的移动客户端 服务器有足够的资源,进出公司的线路非常充足,客户机和服务器之间的复制一般都很好,但我们遇到了间歇性错误,我无法跟踪 昨天我们需要在一个主表中插入550条记录,唯一存在的触发器是标准的合并复制触发器 由于不断与尝试同步的移动设备发生死锁,此插入花费了14个小时 有人对如何避免插入锁以及如何加快整个过程有什么建议吗 ------更新----- 根据一些评论,我在单个插入上运行了一个分析器,我看到了很多类似的事情Sql 合并复制数据库中的插入速度非常慢,sql,sql-server-2008,merge-replication,Sql,Sql Server 2008,Merge Replication,我有一个SQL server,它通过合并复制安装到800个运行SQL CE的移动客户端 服务器有足够的资源,进出公司的线路非常充足,客户机和服务器之间的复制一般都很好,但我们遇到了间歇性错误,我无法跟踪 昨天我们需要在一个主表中插入550条记录,唯一存在的触发器是标准的合并复制触发器 由于不断与尝试同步的移动设备发生死锁,此插入花费了14个小时 有人对如何避免插入锁以及如何加快整个过程有什么建议吗 ------更新----- 根据一些评论,我在单个插入上运行了一个分析器,我看到了很多类似的事情
insert into dbo.MSmerge_current_partition_mappings with (rowlock) (publication_number, tablenick, rowguid, partition_id)
select distinct 1, mc.tablenick, mc.rowguid, v.partition_id
from dbo.MSmerge_contents mc with (rowlock)
JOIN dbo.[MSmerge_JEMProjectME_PromotionResource_PARTITION_VIEW] v with (rowlock)
ON mc.tablenick = 286358001
and mc.rowguid = v.[rowguid]
and mc.marker = @child_marker
and v.partition_id in (select partition_id from dbo.MSmerge_current_partition_mappings cpm with (rowlock) JOIN
dbo.MSmerge_contents mc2 with (rowlock)
ON cpm.rowguid = mc2.rowguid
and mc2.marker = @marker)
where not exists (select * from MSmerge_current_partition_mappings with (readcommitted, rowlock, readpast) where
publication_number = 1 and
tablenick = 286358001 and
rowguid = v.[rowguid] and
partition_id = v.partition_id)
对于许多我不打算插入的表。。。这可能是一个线索吗?我们最近在我们的系统中遇到了与您的系统非常相似的相同行为。原因是msmerge_contents和msmsmerge_current_partition_映射中存在大量数据,通过查看SQL Profiler中读取的行数,我们注意到可能缺少索引。(对于表的简单插入,读取49000 000次似乎有点多) 通过添加两个索引解决了30分钟前的问题:
CREATE NONCLUSTERED INDEX [IX_MSmerge_current_partition_mappings_PERF1] ON [dbo].[MSmerge_current_partition_mappings]
(
[partition_id] ASC
)
INCLUDE ( [rowguid])
CREATE NONCLUSTERED INDEX [IX_msmerge_contents_PERF1] ON [dbo].[MSmerge_contents]
(
[marker] ASC
)
INCLUDE ( [rowguid])
我希望这可以帮助您,它帮助我们将查询时间从5分钟缩短到10秒
--几个小时后
我的同事发现另一个指数进一步将绩效提高了75%:
CREATE NONCLUSTERED INDEX [IX_MSmerge_current_partition_mappings_PERF2] ON [dbo].[MSmerge_current_partition_mappings]
(
[rowguid] ASC,
[partition_id] ASC
)
识别缺失索引
您可以使用下面的脚本来识别缺少的索引,并将其与最有可能提高性能的索引进行排序(有许多这样的脚本在流传,这是从中借用的)
最后,索引到目前为止只起到了作用,看起来合并复制在这个系统上的设置不是很好 然而,使用不触发触发器的大容量插入,然后使用sp_addtabletocontents解决了我们的问题 作为补充说明,我们必须做一个基本的更新 更新表集Column1=Column1
执行大容量插入后,合并复制通知其他链接表它已更改,否则无法正确传播所有数据。1。插入和同步使用的隔离级别是什么?通常,插入应该不是问题。2.你有多少索引?3.是否有非增量索引,并且会导致记录插入到树结构的中间而不是末尾?4.你有聚集索引吗?1。不确定隔离级别。。这只是一个标准的insert语句-2。我们在表A中插入一个标准索引。。然而,合并复制触发器将其粘贴到许多其他表中-3。不在表上,我们正在插入-4。一号。您是否有在复制过程中调用的查询复制过程可能会阻塞案例堆中的整个表(您没有聚集索引)2。表上是否有唯一的密钥?是的,进程和其他复制请求总是出现。。我们有大约800个移动客户端,每个客户端每天复制10次左右,因此它们经常相互重叠,工作也重叠。。只是重新检查。表上没有唯一的键我建议在表上设置顺序聚集索引,并确保复制是基于它进行选择的,并且复制和插入不应在可序列化事务隔离级别上运行,这样您就不会有RangeS-S或RangeI-N锁,如果您有死锁图的话,这很可能是死锁的原因。
SELECT sys.objects.name
, (avg_total_user_cost * avg_user_impact) * (user_seeks + user_scans) AS Impact
, 'CREATE NONCLUSTERED INDEX ix_IndexName ON ' + sys.objects.name COLLATE DATABASE_DEFAULT + ' ( ' + IsNull(mid.equality_columns, '') + CASE WHEN mid.inequality_columns IS NULL
THEN ''
ELSE CASE WHEN mid.equality_columns IS NULL
THEN ''
ELSE ',' END + mid.inequality_columns END + ' ) ' + CASE WHEN mid.included_columns IS NULL
THEN ''
ELSE 'INCLUDE (' + mid.included_columns + ')' END + ';' AS CreateIndexStatement
, mid.equality_columns
, mid.inequality_columns
, mid.included_columns
FROM sys.dm_db_missing_index_group_stats AS migs
INNER JOIN sys.dm_db_missing_index_groups AS mig ON migs.group_handle = mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details AS mid ON mig.index_handle = mid.index_handle AND mid.database_id = DB_ID()
INNER JOIN sys.objects WITH (nolock) ON mid.OBJECT_ID = sys.objects.OBJECT_ID
WHERE (migs.group_handle IN
(
SELECT TOP (500) group_handle
FROM sys.dm_db_missing_index_group_stats WITH (nolock)
ORDER BY (avg_total_user_cost * avg_user_impact) * (user_seeks + user_scans) DESC))
AND OBJECTPROPERTY(sys.objects.OBJECT_ID, 'isusertable')=1
ORDER BY 2 DESC , 3 DESC