2009-05-26 181 views
1

下面的MSSQL2005查詢非常慢。我覺得他們應該加快速度,但我不確定如何。請注意,我編輯內部連接以使用select語句使其更明顯(對於閱讀此問題的人)發生了什麼,儘管這對速度沒有影響(可能執行計劃也是相同的)。有趣的是,我從來沒有真正將關鍵字值組用於計數以外的任何事情,但我不確定是否有辦法利用這一點。SQL優化查詢

select top 1 cde.processPath as 'keywordValue', count(*) as 'total' 
from dbo.ClientDefinitionEntry AS cde INNER JOIN dbo.KeywordValueGroups AS kvg 
ON cde.keywordGroupId = kvg.keywordValueGrpId 
where kvg.[name] = @definitionName 
group by cde.processPath 
order by total desc  

編輯:顯然,人們不斷抱怨我使用子查詢。實際上,這沒有區別。在發佈這個問題之前,我添加了它們,以便更容易地看到發生了什麼。但是他們只是讓事情變得更加混亂,所以我改變了它不使用它們。

編輯:指標的使用:

ClientDefinitionEntry: 
IX_ClientDefinitionEntry |nonclustered located on PRIMARY|clientId, keywordGroupId 

KeyWordValueGroups 
IX_KeywordValueGroups  |nonclustered located on PRIMARY|keywordValueGrpId 
IX_KeywordValueGroups_2 |nonclustered located on PRIMARY|version 
IX_KeywordValueGroups_Name |nonclustered located on PRIMARY|name 
+0

這些表格的示例數據可能會有所幫助...... – 2009-05-26 15:03:31

+0

您有什麼指標?他們是最新的嗎? – 2009-05-26 15:06:39

回答

2

我會確保你有以下索引。

KeywordValueGroups上的ID。

關於KeywordValueGroups的名稱。

ClientDefinitionEntry上的ID與processPath的INCLUDE關聯。

CREATE INDEX [IX_ClientDefinitionEntry_Id_ProcessPath] ON [dbo].[ClientDefinitionEntry] ([keywordGroupId] ASC) INCLUDE ([processPath]) ON [PRIMARY] 
CREATE INDEX [IX_KeywordValueGroups_Id] ON [dbo].[KeywordValueGroups] ([keywordValueGrpId] ASC) 
CREATE INDEX [IX_KeywordValueGroups_Name] ON [dbo].[KeywordValueGroups] ([name] ASC) 

我也會將查詢更改爲以下內容。

select top 1 
    cde.processPath as 'keywordValue', 
    count(*) as 'total' 
from 
    dbo.ClientDefinitionEntry AS cde 
INNER JOIN 
    dbo.KeywordValueGroups AS kvg 
ON 
    cde.keywordGroupId = kvg.keywordValueGrpId 
where 
    kvg.[name] = @definitionName 
group by 
    processPath 
order by 
    total desc 
3

如何執行計劃樣子? 通過查看它,您將瞭解查詢的哪個部分佔用了大部分時間/資源。

您是否在您過濾的列上編制索引?您是否在用於加入的列上編制索引?您是否在用於排序的列上編制索引?

一旦你看了這個,查詢仍然很慢,你可以看看你的數據庫/表是如何分片的(dbcc showcontig),看看是否有必要重建索引。
有一個定期重建索引的維護計劃可能會很有幫助。

3

運行與此選項查詢:

SET SHOWPLAN_TEXT ON

而結果添加到這個問題。

還要檢查,如果你的統計數據是最新的:

SELECT 
    object_name = Object_Name(ind.object_id), 
    IndexName = ind.name, 
    StatisticsDate = STATS_DATE(ind.object_id, ind.index_id) 
FROM SYS.INDEXES ind 
order by STATS_DATE(ind.object_id, ind.index_id) desc 

而關於索引,表定義鍵和外鍵的信息將是有益的。

2

確實沒有足夠的信息來確認。如果您在該查詢中遇到性能問題,那麼這些表必須有一個不重要的數據量,並且您必須缺少重要的索引。

哪些索引肯定會有所幫助,這取決於表格的大小以及KeywordGroupId和KeywordValueGrpId字段中值的分佈。

缺少任何其他信息,我會說你想確保dbo.KeywordValueGroups.[name]已被索引,以及dbo.ClientDefinitionEntry.[keywordGroupId]

由於查詢寫入的方式,單獨的dbo.KeywordValueGroups.[keywordValueGrpId]上的索引無法幫助,但[name], [keywordValueGrpId]上的複合索引可能會。如果您有該索引,則不需要[name]上的專用索引。

僅基於直覺,我可能冒險[name]上的索引是必須,並且cde.keywordGroupId可能很重要。[name], [keywordValueGrpId]上的組合索引是否會有所幫助,取決於具有相同[名稱]的記錄數量。

確切知道的唯一方法是添加索引並查看會發生什麼。

您還需要考慮此查詢的運行頻率(因此,它的速度有多重要)以及底層數據更改的頻率。根據您的具體情況,速度的增加可能無法證明維護索引所增加的成本。

0

不知道我們有多少條記錄在談論但這: 順序按總遞減 是一個計算列意思就是每一行每一計算將不得不做可以做排序前。可能這是放慢速度的原因之一,但我認爲沒有辦法解決這個問題。如果您在加入後只有幾條記錄,則不是問題,但如果有很多記錄,則可能是問題。

我會先專注於索引。我們經常忘記,當我們創建foriegn鍵時,它們不會自動編入索引。檢查連接的兩個部分是否都編入索引。

由於您在參數中傳遞值,因此您可能還有參數嗅探問題。谷歌這個技術來解決這個問題。