2009-05-26 131 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键时,它们不会自动编入索引。检查连接的两个部分是否都编入索引。

由于您在参数中传递值,因此您可能还有参数嗅探问题。谷歌这个技术来解决这个问题。