2013-02-23 48 views
3

我已經在數據庫中按照DTA的建議添加非結束索引會提高性能嗎?

表鋪

  • ShopId
  • SHOPNAME
  • 所有者定義的以下表
  • 橫幅
  • 部首
  • CityId
  • ShopImageId
  • 活動

市表

  • CityId
  • CITYNAME
  • CountryId
  • RegionId

表國家

  • CountryId
  • 國家或地區名稱
  • RegionId

REGION

  • RegionId
  • 個RegionName

ShopImages

  • 編號
  • 圖片
  • ShopId

這裏是我的選擇查詢

SELECT ShopName, Owner, CityName, CountryName,RegionName 
FROM Shop S 
INNER JOIN City CT ON CT.CityId=S.CityId 
INNER JOIN Country CO ON CO.CountryId=CT.CountryId 
INNER JOIN Region R ON CT.RegionId=R.RegionId 
LEFT OUTER JOIN ShopImages SI ON S.ShopImageId=SI.Id 

WHERE S.Banner like '%restaurant%' OR S.Description like '%restaurant%' 
AND S.CityId=10 AND S.Active=1 

截至目前市表已有約300萬條記錄&店鋪有 40,000,000條記錄。

獲取記錄需要時間。所有的聚集索引(主鍵)都已經定義好了。

我想在DTA(數據庫優化顧問)的幫助下進行優化。 它建議我加入以下指標

CREATE NONCLUSTERED INDEX 
    [_dta_index_CITY_9_2098106515__K9_K20_K1_K2] ON [dbo].[CITY] 
(
    [COUNTRYID] ASC, 
    [REGIONID] ASC, 
    [CITYID] ASC, 
    [CITYNAME] ASC 
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) 
    ON [PRIMARY] 

是否值得加入這個指標?我可以從DTA採取所有建議嗎?它建議增加一些統計數字。

怎麼樣能改善我的上面的查詢?

+3

'INNER JOIN Region R Region.RegionId = R.RegionId'?你確定這是正確的嗎? – 2013-02-23 14:09:27

+0

@JoachimIsaksson,謝謝你。我現在更新了。錯字錯誤:) – Billa 2013-02-23 14:10:43

+0

不過,我會假設'內部聯接區域R在CT.RegionId = R.RegionId'上:) – 2013-02-23 14:11:19

回答

2

當分析索引時,很難說DTA是錯誤,因爲我不知道數據分佈和它的確如此,但是我在主鍵之外添加的第一個索引是(可能是複合的)索引SHOP.CityIDSHOP.Active

我不能給你任何絕對沒有測試,但這是推理。

由於您基本上在SHOP上進行篩選,並且在任何其他表上沒有篩選器,所以查詢的繁重工作很可能是在篩選SHOP中的50M個行。

如果數據庫從任何其他表開始連接,則未過濾的連接將導致3M行鍼對CITY,並且以篩選SHOP開頭的結果很可能會少得多。有充分的理由,編譯器喜歡「更少」。

這是SHOP上的過濾器;

WHERE S.Banner like '%restaurant%' OR S.Description like '%restaurant%' 
    AND S.CityId=10 AND S.Active=1 

由於LIKE%開始基本上不能在所有使用索引的查詢時,你要窄,快速過濾儘可能通過S.CityId=10 AND S.Active=1完成。如果您對這些索引進行索引,則其他兩個條件將不需要掃描使用索引而不是掃描的幾行,而可能需要掃描50M行。

我能看到索引建議的唯一原因會產生很大的影響,如果CITY表中有大量的字段,並且索引將允許數據庫從磁盤讀取更少的數據以獲得領域。不是說這是事實,但只是嘗試它才能確定。

+0

尼斯。Wonderting DTA怎麼不提示這個:)它只是建議我創建統計[_dta_stat_1250103494_8_19] ON [dbo]。[商店]([ACTIVE],[CITYID]) – Billa 2013-02-23 14:53:19

+1

在[ACTIVE],[CITYID]上添加索引是否會影響其他查詢中的任何其他問題,但他們沒有在WHERE子句中使用此組合? – Billa 2013-02-23 14:54:55

+0

我認爲相反的順序(即,[CityId],[Active])會更可取,如果Active甚至是有價值的(只有兩個可能的值不一定有用,可能取決於分佈) – 2013-02-23 14:58:09

1

在某些情況下,您可能想重新考慮在主鍵列上使用聚簇索引。

例如,如果您通常在給定城市中搜索商店(如果示例查詢是「典型查詢」,則會出現這種情況),將商店聚集在CityId上可能會非常有益(因此所有商店在給定的城市被分組在一起)

+0

我已經爲ShopId創建了聚簇索引,因爲它是主鍵。我認爲sql server會自動在ShopId上創建聚集索引。 – Billa 2013-02-23 15:14:45

+0

是的,那是我寫給你的印象。我所說的是你可能想重新考慮這一點。 (您可以使ShopId上的索引非羣集,並在CityId上創建羣集,如果這樣更符合您的要求。) – 2013-02-23 15:18:30

+0

我還有其他查詢,例如WHERE ShopId = 5,僅用於獲取Shop Item,其中不包括City。我希望在ShopId上集羣是有意義的。請分享你的想法:) – Billa 2013-02-23 16:26:23

相關問題