Sql server SQL Server:选择前1名与选择前2名或更多速度问题

Sql server SQL Server:选择前1名与选择前2名或更多速度问题,sql-server,Sql Server,我在selecttop1上看到的查询时间与将top1更改为其他类似top2或top1000的查询时间截然不同 TOPanything>1在毫秒内运行,TOP 1在12分钟内运行 这是查询的外观: SELECT TOP ? Column1, Column2, Column3, Column4, Column5, Column6, Column7, Column8 AS Column9, Column10, Column11, Column12 AS

我在
selecttop1
上看到的查询时间与将
top1
更改为其他类似
top2
top1000
的查询时间截然不同

TOP
anything>1在毫秒内运行,
TOP 1
在12分钟内运行

这是查询的外观:

SELECT TOP ? 
    Column1, Column2, Column3,
    Column4, Column5, Column6,
    Column7,
    Column8 AS Column9,
    Column10, Column11,
    Column12 AS Column13,
    Column14,
    Object1.Column15 AS Column16,
    ? AS Column17,
    Column18
FROM
    Object2 Object1
INNER JOIN 
    CONTAINSTABLE(Object2, *, ?, ?) key_table ON Object1.Column19 = Object3.Column20
WHERE
    (Column6 IN (SELECT DISTINCT
                     Object4.Column21
                 FROM Object4
                 INNER JOIN Object5 ON Object4.Column22 = Object5.Column22
                 WHERE Object5.Column23 = ?
                   AND Object4.Column24 = ?))
ORDER BY 
    Column2 ASC;
如您所见,我正在通过表PK上的
CONTAINSTABLE
加入全文查询。我还检查结果列是否位于子选择中。我已经在()中的
in
select中完成了子选择,并将其更改为更多的
internaljoin
。我向它展示这是因为代码是这样的。无论哪种方式,它都会做同样的事情

我发现的问题是执行计划。如果我要求前2名或更多,它将以完全不同的方式加入WHERE列。您可以看到我在索引Seek Object4.Index3中添加的查询计划中的差异。在top_issue_over_one中,只有2个seek谓词。在最上面的问题中有3个,第三个是子选择中的列。当这种情况发生时,它必须循环表以获取数据,每个表中可能有数百万条记录。您还可以从计划中看到存在的索引。它们在所有列上都有索引

为了回答一些问题,我会主动询问,是的,排序列已编制索引,是的,如果我将其取下,它将在这两种情况下快速运行。此外,如果我删除全文查询,它将在这两个页面上快速运行。正是这一切的结合使它发生了


我很好奇,是否有人看到了这一点,是否知道为什么它在TOP 1和TOP其他任何项目上的计划有所不同?

根据查询过程中涉及的阶段,TOP代表一个过滤器,是最后一步,您是否可以测试另一个场景,在该场景中更改查询并放置

SET ROWCOUNT 1 
代替TOP 1并评估差异,另一件事是尝试应用

DBCC FREEPROCCACHE

显然是在开发环境中

根据查询过程中涉及的阶段,顶部代表一个过滤器,是最后一步,您是否可以测试另一个场景,在该场景中更改查询并放置

SET ROWCOUNT 1 
代替TOP 1并评估差异,另一件事是尝试应用

DBCC FREEPROCCACHE

显然是在开发环境中

这些真的是您的表名和列名吗?那应该是死罪!您可以在这里看到查询计划:看起来像一些统计数据issue@FrisbeeObject2 Object1只是这个查询中完全荒谬的别名的另一个例子。我怀疑(并且真的希望)这些名字是假的。如果我在一个真实的环境中工作,我会开枪自杀。它被匿名化到几乎不可能破译正在发生的事情。这些真的是你的表名和列名吗?那应该是死罪!您可以在这里看到查询计划:看起来像一些统计数据issue@FrisbeeObject2 Object1只是这个查询中完全荒谬的别名的另一个例子。我怀疑(并且真的希望)这些名字是假的。如果我在真实的环境中工作,我会开枪自杀。它被匿名化,几乎无法破译正在发生的事情。我已经尝试将行数设置为1,我应该这么说,对不起。我还没有尝试杀死缓存,我将把数据库带到我的开发环境中,然后尝试。我已经尝试设置行数1,我应该这么说,对不起。我还没有尝试杀死缓存,我将把DB带到我的开发环境中并尝试一下。