以下MSSQL2005查询非常慢。我觉得他们应该成为加快速度的方法,但我不确定如何。请注意,我编辑了内部联接以使用select语句使(对于阅读此问题的人)更明显的是发生了什么,尽管这对速度没有影响(执行计划可能是相同的两种方式)。有趣的是,我从来没有实际使用关键字值组来计算任何数量,但我不确定是否有办法利用它。
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 :(得分:3)
执行计划如何? 通过查看它,您将了解查询的哪一部分占用最多的时间/资源。
您是否对要过滤的列进行了索引?您是否对用于加入的列编制索引?您是否对用于排序的列进行了索引?
一旦你看了这个,并且查询仍然很慢,你可以看一下你的数据库/表是如何分段的(dbcc showcontig),看看是否有必要重建索引。登记/> 制定维护计划可能会有所帮助,该计划会定期重建索引。
答案 1 :(得分:3)
使用此选项运行查询:
设置SHOWPLAN_TEXT
并将结果添加到问题中。
另请检查您的统计信息是否是最新的:
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 :(得分:2)
确实没有足够的信息可以知道。如果您在该查询中遇到性能问题,那么表必须具有非常重要的数据量,并且您必须缺少重要的索引。
哪些索引肯定会有所帮助,这在很大程度上取决于表的大小,以及在较小程度上取决于KeywordGroupId和KeywordValueGrpId字段中值的分布。
缺少任何其他信息,我想说您要确保dbo.KeywordValueGroups.[name]
被编入索引,以及dbo.ClientDefinitionEntry.[keywordGroupId]
。
由于编写查询的方式,仅dbo.KeywordValueGroups.[keywordValueGrpId]
上的索引无法帮助,但[name], [keywordValueGrpId]
上的复合索引可能会有所帮助。如果您有该索引,则不需要[name]
上的专用索引。
仅基于直觉,我可能会担心[name]
上的索引是必须,而cde.keywordGroupId可能很重要。 [name], [keywordValueGrpId]
上的复合索引是否有帮助,取决于具有相同[名称]的记录数。
唯一可以确定的方法是添加索引,看看会发生什么。
您还需要考虑此查询运行的频率(因此,使其快速运行的重要性)以及基础数据更改的频率。根据您的具体情况,速度的提高可能无法证明维护索引的额外成本。
答案 3 :(得分: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
答案 4 :(得分:0)
不确定我们谈论的记录有多少但是这个: 按总额排序 在计算列上,意味着每行上的每个计算都必须在排序完成之前完成。可能这是减缓它的事情之一,但我认为没有办法摆脱那个特定的问题。如果您在加入后只有一些记录,则不会有问题,但如果有很多记录可能会出现问题。
我首先专注于索引。我们经常忘记,当我们创建foriegn键时,它们不会自动编入索引。检查连接的两个部分是否都已编入索引。
由于您在参数中传递值,因此您可能还有参数嗅探问题。谷歌这是解决这个问题的技巧。