为什么在SQL Server中的索引列上执行top(1)会变慢?

Toa*_*oad 20 t-sql sql-server performance query-optimization

我对以下内容感到困惑.我有一个大约1000万行的数据库,并且(在其他索引中)1列(campaignid_int)是一个索引.

现在我有700k行,其中campaignid确实是3835

对于所有这些行,connectionid是相同的.

我只是想找出这个连接.

 use messaging_db;
 SELECT     TOP (1) connectionid
 FROM         outgoing_messages WITH (NOLOCK)
 WHERE     (campaignid_int = 3835)
Run Code Online (Sandbox Code Playgroud)

现在这个查询大约需要30秒才能执行!

我(用我的小数据库知识)会期望它会占用任何行,并返回给我那个connectionid

如果我为只有1个条目的广告系列测试同样的查询,那么它的速度非常快.因此索引有效.

我该如何解决这个问题,为什么这不起作用?

编辑:

estimated execution plan:

select (0%) - top (0%) - clustered index scan (100%)
Run Code Online (Sandbox Code Playgroud)

小智 17

由于统计信息,您应该明确要求优化器使用您创建的索引而不是群集索引.

SELECT  TOP (1) connectionid
FROM    outgoing_messages WITH (NOLOCK, index(idx_connectionid))
WHERE  (campaignid_int = 3835)
Run Code Online (Sandbox Code Playgroud)

我希望它能解决这个问题.

此致,恩里克


小智 9

我最近遇到了同样的问题,解决起来非常简单(至少在某些情况下).

如果ORDER BY在索引的任何或部分列上添加-clause,则应解决该问题.这至少解决了我的问题.


Gre*_*ech 5

您没有ORDER BY在查询中指定子句,因此没有指示优化器应该从中选择前 1 项的排序顺序。SQL Server 不会只是随机取一行,它会按某些内容对行进行排序并取前 1,并且它可能会选择按次优排序。我建议您添加一个ORDER BY x子句,其中x作为该表上的聚集键可能是最快的。

这可能无法解决您的问题——事实上,我不确定我是否希望根据您提供的统计数据来解决问题——但是 (a) 它不会受到伤害,并且 (b) 您将能够解决这个问题作为一个促成因素。