2013-08-21 50 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