我有一张大表(1400万条记录),我将需要应用合并语句(基本上需要更新/插入/删除一些数据)。由于桌子很大,这就是我的策略:
insert into #ProjectUnitsCacheDetailExisting([ProjectUnitsCacheId], UniverseCode,CitiCode)
SELECT ProjectUnitsCacheId, UniverseCode,CitiCode
FROM dbo.ProjectUnitsCacheDetail WHERE ProjectUnitsCacheId = @CacheID
;MERGE #ProjectUnitsCacheDetailExisting AS T
USING @ProjectUnitsCacheDetail AS S
ON (t.UniverseCode = s.UniverseCode and t.CitiCode = s.CitiCode)
WHEN NOT MATCHED BY TARGET
THEN
INSERT(ActionType,ProjectUnitsCacheId,UniverseCode,CitiCode)
VALUES('INSERT', @CacheId,s.UniverseCode,s.CitiCode)
insert into ProjectUnitsCacheDetail(
ProjectUnitsCacheId, UniverseCode,CitiCode)
select @CacheId,UniverseCode,CitiCode
from #ProjectUnitsCacheDetailExisting
where actionType = 'INSERT'
基本上先确定需要在临时表中添加,更新和删除的内容,然后删除/添加/更新数据。这比直接在我的1400万条记录表上应用合并语句要快得多。
然后我了解了分区表,认为对我来说这是一个很好的用法。因此,我创建了一个被10分区的表(分区键为ProjectUnitsCacheId%10),然后将merge语句直接应用于新表。但是,它变得慢得多。
;MERGE ProjectUnitsCacheDetailTest AS T
USING @ProjectUnitsCacheDetail AS S
ON (t.UniverseCode = s.UniverseCode and t.CitiCode = s.CitiCode) AND T.ProjectUnitsCacheId=@CacheID
WHEN NOT MATCHED BY TARGET
THEN INSERT ( ProjectUnitsCacheId,UniverseCode,CitiCode)values( @CacheId,s.UniverseCode,s.CitiCode)
....delete action
....update action
此方法比临时表方法慢10倍。如果我直接使用@CacheId作为参数进行选择,则分区表的确会更快地返回数据。那么可能是什么问题?
答案 0 :(得分:1)
问题在于,现在您的表已分区,其内容被拆分到不同的磁盘位置和索引中。因此,除非您要比较的数据与1个分区匹配,否则诸如更新,插入或删除之类的操作最有可能要比完整的,未分区的计数器部分慢。
分区表非常适合按分区列查询数据,并且一次只能处理1个分区。如果您倾向于在所有分区之间进行操作,则可能要查看分区键,或者考虑不对表进行分区。