Sql-Server

非常大的表使應用程序性能太慢

  • May 24, 2020

我們有一個舊應用程序存在性能問題。我將其縮小到系統中絕對需要注意的幾個點。

我發現這個應用程序中引用了一個表,其中包含 1,332,730,786 條記錄。

Table IDSelection 
IDType varchar(20) NOT NULL, 
SelectID int NOT NULL, 
UnID int NOT NULL, 
Batch int NULL

表有以下索引

IX_IDSelection_UnID nonclustered located on PRIMARY UnID
PK_UIDSelection clustered, unique, primary key located on PRIMARY SelectID, IDType, UnID

我的擔憂是 1. 該表具有復合主鍵,其中 IDType 中的一些條目是空字元串(雖然不是 NULL)。2. 像下面這樣針對這個表執行簡單的 SELECT 查詢需要相當長的時間。

select * from IDSelection where IDType <> '' and Batch is not NULL ORDER by Batch desc  -- cluster index scan
select * from IDSelection where Batch = 9977    -- 8 minutes run for 19 records
select * from IDSelection where IDType = 'ParentID' and Batch is not NULL  -- 9 min 3614603 rows

如果我在 WHERE 子句中使用索引 UnID,如下所示,性能非常好

SELECT * FROM IDSelection where UnID = 1093510

索引碎片在這裡不是問題。是否有助於添加身份主鍵並將目前複合鍵設為

$$ non clustered unique index $$幫助?我們還有哪些其他選擇? 數據庫版本為 MS SQL 2014 Enterprise

您認為創建一個附加索引需要多長時間?DML 多久執行一次?這張表是否經常被閱讀?

鑑於這個怪物有超過 10 億行,我將創建帶有列的單獨過濾表SelectID, IDType, UnID, Batch並在那裡應用適當的索引。

這些需要一個以 . 開頭的索引Batch。在第一種情況下ORDER BY,在第二種情況下WHERE

select * from IDSelection where IDType <> '' and Batch is not NULL ORDER by Batch desc  -- cluster index scan
select * from IDSelection where Batch = 9977    -- 8 minutes run for 19 records

這需要INDEX(ParentID, Batch)按順序:

select * from IDSelection where IDType = 'ParentID' and Batch is not NULL  -- 9 min 3614603 rows

您已經有一個索引(或至少從)開始UnID,因此這很快:

SELECT * FROM IDSelection where UnID = 1093510

*除非您真的想要所有列,否則不要使用。如果您只需要選擇一小組列,可以將它們附加到索引的末尾,從而使其“覆蓋”。

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