2011-03-25 49 views
3

我有一個大約115k行的表。事情是這樣的:在SQL Server 2005中的巨大表上的「不在」更新

Table: People 
Column: ID PRIMARY KEY INT IDENTITY NOT NULL 
Column: SpecialCode NVARCHAR(255) NULL 
Column: IsActive BIT NOT NULL 

起初,我有一個指標定義,像這樣:

PK_IDX (clustered) -- clustered index on primary key 
IDX_SpecialCode (non clustered, non-unique) -- index on the SpecialCode column 

而且我做一個更新,像這樣:

Update People set IsActive = 0 
Where SpecialCode not in ('...enormous list of special codes....') 

這個龐大的名單基本上是表中99%的用戶。

此更新需要我的服務器上永遠。作爲測試,我將「not in」子句中的特殊代碼列表修剪爲表中用戶的1%,並且我的執行計劃最終在PK_IDX索引上使用INDEX SCAN,而不是IDX_SpecialCode索引。認爲它會使用。

所以,我想,也許我需要修改IDX_SpecialCode以便它包含在它的列「IsActive」。我這樣做,我仍然看到執行計劃默認爲PK_IDX索引掃描,我的查詢仍然需要很長時間才能運行。

所以 - 什麼是做這種性質的更新比較正確的做法?我有用戶的我想排除從更新的列表中,但試圖避免從數據庫中加載所有員工的特殊代碼,在我的應用端我的列表中過濾掉那些不是,然後運行我的查詢與子句中,這將是我實際使用中的小得多的列表。

感謝

+0

指標被忽略,這就是爲什麼SQL是忽略索引:) – 2011-03-25 17:32:05

回答

3

如果您有要排除的員工,爲什麼不填充的索引表與PK_IDs並做了:

Update People 
set IsActive = 0 
Where NOT EXISTS (SELECT NULL 
        FROM lookuptable l 
        WHERE l.PK = People.PK) 

你得到索引掃描,因爲SQL Server不傻,並認識到查看整個表格而不是一次檢查100個不同的標準更有意義。如果您的統計信息是最新的,優化程序就會知道您的IN語句涵蓋了多少表,並且如果它認爲速度更快,它將執行表或聚簇索引掃描。

+0

也許是最好的答案在這裏, 謝謝。 – Mustafakidd 2011-03-25 17:34:36

+0

@Mustafakidd - 很樂意幫忙 – JNK 2011-03-25 17:42:18

0

有什麼辦法,你可以使用你想排除的,而不是他們的代碼用戶的ID - 即使是在比較ID可能比字符串快索引值。

0

我覺得現在的問題是你SpecialCode NVARCHAR(255)。 Sql Server中的字符串比較非常慢。考慮更改您的查詢以使用這些ID。此外,請儘量避免NVarchar。如果不在乎Unicode,請改爲使用Varchar

此外,檢查你的數據庫歸類,看它是否實例歸類匹配的。確保你沒有硬盤性能問題。

1

當您使用NOT子句時,SQL-Server索引被忽略。這就是爲什麼你看到執行計劃忽略你的索引。 < - 參考:第6頁。MCTS考試70-433數據庫開發SQL 2008(我正在閱讀此刻)

這可能是值得看看全文索引,雖然我不知道是否會發生同樣的情況(我避風港「T已取得了一個方塊,它成立的那一刻進行測試)

心連心當您使用NOT子句

+0

從來不知道 - 謝謝參考。 – Mustafakidd 2011-03-25 17:34:09