Sql-Server

SQL 暫存表:主鍵集群或堆

  • November 11, 2018

我們正在使用舊的平面 txt 文件並將它們插入到帶有 SSIS 的階段表中。問題出現了表是否應該具有主聚集鍵索引。這是沒有轉換的直接平面文件導入。

create table dbo.CustomerTransaction
(
    CustomerName varchar(255),
    PurchaseLocation varchar(255),
    Productid  int,
    AmountSold float,
    CustomerAddress varchar(50)
)

create table dbo.CustomerTransaction
(
    -- discussion for adding this column
    CustomerTransactionId int primary key clustered identity(1,1) 

    CustomerName varchar(255),
    PurchaseLocation varchar(255),
    Productid  int,
    AmountSold float,
    CustomerAddress varchar(50)
)

-- both tables have nonclustered indexes
create nonclustered index idx_ProductId on dbo.CustomerTransaction(ProductId)
create nonclustered index idx_CustomerAddress on dbo.CustomerTransaction(CustomerAddress)

-- Actually have more indexes, tables above are just for sample 
  1. 在 ETL 之前,暫存表被截斷。沒有刪除和更新。僅插入。
truncate table dbo.[CustomerTransaction]

2)然後在ETL之前禁用所有索引。

alter index all on dbo.[CustomerTransaction] DISABLE

3)我們用預設的快速載入進行SSIS數據流,我讀的相當於批量插入。這裡沒有發生任何轉換。

  1. 然後在導入完成後重新啟用所有索引。
alter index all on dbo.[CustomerTransaction] REBUILD
  1. 然後在 join 和 where 子句中選擇暫存表,並將其放入數據倉庫。這就是為什麼我們有非聚集索引的原因。載入數據倉庫後,我們截斷臨時表。

我們聽到的資訊是 ETL 階段表就像堆一樣好。但是,還要學習堆的碎片和性能問題。閱讀以下所有文章

我正在閱讀相互矛盾的意見。有人說二叉樹集群是導入 ETL 的維護難題。其他人說堆在碎片化方面存在性能問題。我們的性能測試並沒有顯示出太大的差異,但我們的數據可能會在以後發生變化。所以我們需要做出一個好的設計決策。

https://sqlsunday.com/2016/09/01/compelling-case-for-heaps/

https://www.mssqltips.com/sqlservertip/4961/sql-server-insert-performance-for-clustered-indexes-vs-heap-tables/

http://kejser.org/clustered-indexes-vs-heaps/

https://www.red-gate.com/simple-talk/sql/database-administration/sql-server-heaps-and-their-fragmentation/

我們知道擁有標識的一個很好的理由是行標籤,但是問題主要是關於內部和性能。

我們有一個類似的場景,最近將我們的暫存表從聚集索引切換到堆。對我們來說,第一個很大的優勢是我們希望允許並發 SSIS 載入到同一個臨時表中。您可以使用聚集索引來做到這一點,但您可能會遇到很多阻塞,尤其是使用標識列時。第二大優勢是減少載入臨時表的成本。我們發現,與聚集索引相比,我們在堆上的載入速度要快得多。

我們的性能測試並沒有顯示出太大的差異,但我們的數據可能會在以後發生變化。所以我們需要做出一個好的設計決策。

你確定這是真的嗎?在問題中,您說您在載入之前截斷了臨時表。如果載入過程的某些部分發生更改,那麼在表為空時添加或刪除聚集索引應該非常簡單。不涉及數據移動。聽起來您不會從聚集索引中獲得任何好處,所以我會嘗試將其作為堆並監控性能。

引用自:https://dba.stackexchange.com/questions/222247