2015-07-10 53 views
0

這是我的查詢 - 最後一個查詢是什麼導致我很痛: address.postcode字段是一個varchar(14)和你可以看到輸入格式,用戶在發送執行計劃顯示排序 - 但無法解決因爲查詢

DECLARE @ZipCode NVARCHAR(MAX) = ('06409;06471;11763;06443;06371;11949;11946;11742') 

IF OBJECT_ID('tempdb..#ZipCodes') IS NOT NULL DROP TABLE #ZipCodes; 

CREATE TABLE #ZipCodes (
Zipcode NVARCHAR(6) 
) 

INSERT INTO #ZipCodes (Zipcode) 
SELECT zip.Token + '%' 
FROM DMS.fn_SplitList(@ZipCode, ';') zip 

CREATE NONCLUSTERED INDEX [idx_Zip] ON #ZipCodes (Zipcode) 

IF OBJECT_ID('tempdb..#ZipCodesConstituents') IS NOT NULL DROP TABLE #ZipCodesConstituents; 

CREATE TABLE #ZipCodesConstituents (
ConstituentID UNIQUEIDENTIFIER 
, PostCode NVARCHAR(12) 
) 
CREATE NONCLUSTERED INDEX [idx_ZipCodesConstituents] ON #ZipCodesConstituents (ConstituentID, PostCode) 

INSERT INTO #ZipCodesConstituents (ConstituentID, PostCode) 
SELECT a.CONSTITUENTID 
, a.POSTCODE 
FROM #ZipCodes zip 
JOIN DMS.address a 
    ON a.POSTCODE LIKE zip.Zipcode 
where a.ISPRIMARY = 1 

我試圖附加執行計劃 - 但沒有任何運氣... 基本的代碼段有61.9%的預估成本 和排序是61.5%

+0

問題是什麼? – cyroxis

+0

我想改善性能,並排序導致過剩。想就如何擺脫排序或其他優化方式想任何想法。 –

+0

爲什麼在插入之前創建索引?我不知道沒有執行計劃的排序,但索引會減慢每個插入,因爲系統必須更新每插入一行的索引。這實際上可能是導致排序的原因,因爲sql尋找一種方法來最小化索引的影響。 – Randall

回答

0

我試圖評估行爲,但在我的測試中,我不能在最後的強制排序運算符。但是我看到的是以下兩個問題。

  1. 您創建索引,然後插入表中。這可能是有害的。並非所有情況下都是如此,但它可能會強制查詢中的排序,因爲SQL Server會在插入過程中嘗試確保正確的順序以幫助索引進行重新組織。
  2. 您使用UNIQUEIDENTIFIER作爲您的主鍵。這在某種程度上可能是有用的,但我認爲在你的情況下,一個簡單的IDENTITY(1,1)列就足夠了,不是嗎?您的索引中的UNIQUEIDENTIFIER將嚴重強化分片。這樣解決這個問題可能不是最好的想法。

我測試了兩個變種,測試集爲100.000行。 這些都是我導致執行成本的測量:

  • 在所有情況下,成本更低顯著,如果該索引是的#ZipCodesConstituentsINSERT後創建
  • 使用INDENTITY而不是UNIQUEIDENTIFIER可以提高性能。
  • 如果您更經常地運行這種查詢,在您的地址表上添加索引將是明智之舉。

以下是成本點的測量(CP) - 越低越好:前

  • UniqueIdentifier +指數:20 CP爲Insert
  • UniqueIdentifier +插入後的索引:對於索引Insert + 7(其中SORT發生)爲8 cp。
  • Identity +索引之前:18釐泊爲Insert
  • Identity +索引後:7釐泊爲Insert + 6用於索引
  • Identity +指數+後指數上Address:3爲Insert + 6爲索引

獲勝者是:Identity列+索引,也可能是您的Address索引。

我用來提升雙方的陳述(UniqueIdentifierIdentity)的指數是這一個:

CREATE NONCLUSTERED INDEX [NCI_Adress_IsPrimary_Postcode] 
ON Address ([IsPrimary],[PostCode]) 
INCLUDE ([Constituentid]) 

在我的測試用例花了13 CP來構建它。如果你只是使用一次,這將不會有幫助!如果你經常使用這種說法,甚至有時候每天使用一次,這可能對你有用。

希望這能解決您的問題。

+0

謝謝@Ionic。我必須保留uniqueidentifier來連接到另一個表,但我認爲在插入後添加索引並添加Address表索引後,我將獲得我期望的最佳性能 - 因爲我必須保留uniqueidentifier。 –

+0

是的,'identity'和'uniqueidentifier'之間的區別在這個用例中是微不足道的。 – Ionic