为什么合并语句在分区表中要慢得多?

时间:2018-12-18 18:08:26

标签: sql-server tsql

我有一张大表(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作为参数进行选择,则分区表的确会更快地返回数据。那么可能是什么问题?

1 个答案:

答案 0 :(得分:1)

问题在于,现在您的表已分区,其内容被拆分到不同的磁盘位置和索引中。因此,除非您要比较的数据与1个分区匹配,否则诸如更新,插入或删除之类的操作最有可能要比完整的,未分区的计数器部分慢。

分区表非常适合按分区列查询数据,并且一次只能处理1个分区。如果您倾向于在所有分区之间进行操作,则可能要查看分区键,或者考虑不对表进行分区。