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带到我的开发环境中并尝试一下。