2013-08-21 172 views
0

由于某种原因,TSql合并指令减慢。tsql合并速度减慢

我合并批量批量大小等于10000条记录的数据批次,我看到从一批到另一批合并花费的时间越来越长。

这里是合并指令:

MERGE [dbo].[SResult] AS target 
      USING [dbo].[SResultTemp] AS source 
      ON (target.QSId = source.QSId 
       and target.ResultId = source.ResultId 
       and target.EngineId = source.EngineId) 
      WHEN NOT MATCHED THEN INSERT 
       (QSId, ResultId, EngineId, Position) 
      values 
       (source.QSId, source.ResultId, source.EngineId, source.Position); 

源表声明如下

CREATE TABLE [dbo].[SResultTemp](
     [QSId] int not null, 
     [ResultId] int not null, 
     [EngineId] int not null, 
     [Position] int not null, 
     CONSTRAINT [PK_SResultTemp] PRIMARY KEY CLUSTERED(
      [QSId], [ResultId], [EngineId], [Position] ASC 
     )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
     ) ON [PRIMARY] 

目标是相同的,但它有附加字段SResultId作为主键和另一组的索引的:

PK_SResult - primary

IX_SResult_QS Id_ResultId - 非唯一,非聚集

IX_SResult_EngineId - 非唯一的非聚集

UX_SResult_EngineId_QSId_Position - 唯一的非聚集

和这里是我在日志中看到:

Results Upload: SResult took 00:00:01.0008344 
    Results Upload: SResult took 00:00:18.1046734 
    Results Upload: SResult took 00:00:17.9797846 
    Results Upload: SResult took 00:00:27.7828817 
    Results Upload: SResult took 00:01:30.4140091 
    Results Upload: SResult took 00:03:17.6433416 
    Results Upload: SResult took 00:03:21.3761251 
    Results Upload: SResult took 00:06:07.2555342 
    Results Upload: SResult took 00:06:56.2423653 
    Results Upload: SResult took 00:06:57.1729179 
    Results Upload: SResult took 00:07:09.7221083 

而且,我的工作与多个表,所以其他表没有这样的规律性。谁能帮忙?

谢谢!

+1

公平你的PK有点失控。 – ChaosPandion

+1

由于PK获取片段插入速度会降低(并且比你想象的要快很多) – Paparazzi

回答

1

由于索引片段插入速度降低。
正如你所见,可以迅速降解。
如果您可以按照PK顺序插入,那么这将减少碎片。
填充索引会减慢碎片。
插入完成后,您可以删除所有非聚集索引然后重建吗?

是SResultId身份?

为什么索引设计?
您有一个与SResultTemp上的PK不同的唯一约束。

索引加速选择,但它们减慢了插入和更新。
加入索引将有所帮助,但现在索引已拆分。

我的建议是将其分解为唯一性和测试所需的索引。

+0

,看起来唯一的索引是杀死性能。如果我禁用它,不会再发生退化。 所以问题是如何在不使用唯一索引的情况下授予唯一性。 – user2703790

+0

请勿插入重复项。 – Paparazzi

+0

不要插入重复是一个好主意,但有时候有人可能会破坏某些东西。一旦它发生了,所以我们必须创建这个索引来防止这样的问题。 那么,解决方案是非常简单的: 有人注意到,降解只在发生非常具体的数据: 所有沐浴具有相同的ENGINEID和QSId(这是该系列批次的独特在换句话说没有其他进程可以创建。任何具有相同EngineId的记录)。 所以实际上只有位置索引起作用。 所以索引字段洗牌帮助:新的唯一索引UX_SResult_EngineId_Position_QSId绝对没有给出降解 – user2703790

1

当然,它需要更长的时间,你会期望有一个有四个领域的聚类PK?在合并过程中,您不断重新排列表格中的所有记录。

+0

PK看起来很好 - 唯一索引实际上正在杀死性能 – user2703790

0

有两个问题:

  1. 增加索引和作为添加越来越多的行所得到的修的工作
  2. 接通子句

    ON (target.QSId = source.QSId 
        and target.ResultId = source.ResultId 
        and target.EngineId = source.EngineId) 
    

导致增加需要在目标中进行检查,因为越来越多的行需要进行比较。

摆脱索引会极大地减慢ON子句的检查速度。我们在这里有利益冲突。

+0

没错,但问题是,我有七个表像这样复杂的PK。他们都没有显示合并退化。 – user2703790

+0

@ user2703790我很惊讶,你有你所看到的合并没有退化严重索引的表。请发布样品。 – Paparazzi

+0

当唯一索引关闭时,子句在两个其他索引上工作并且不会发生降级。 – user2703790