繁体   English   中英

查询执行计划(SQL Server 2000)中的意外估计行

[英]Unexpected estimated rows in query execution plan (Sql Server 2000)

如果我运行此查询

select user from largetable where largetable.user = 1155 

(请注意,我查询用户只是为了将其简化为最简单的情况)

再看一下执行计划,计划进行索引搜索[大表对用户有索引],并且估计的行是正确的29。

但是如果我这样做

select user from largetable where largetable.user = (select user from users where externalid = 100)

[子查询的结果是单值1155,就像上面我硬编码时一样]

查询优化器估计结果中有117,000行。 大表中约有600万行,用户中有1700行。 当然,当我运行查询时,尽管估计行数很大,但我仍会返回正确的29行。

我已经在relevent索引的两个表上使用fullscan更新了统计信息,当我查看统计信息时,它们似乎是正确的。

值得注意的是,对于任何给定的用户,大表中最多只能有3,000行。

那么,为什么估算的执行计划会显示如此大量的估算行呢? 基于统计信息,优化器是否不应该知道它正在寻找具有29条相应行的结果,或者即使它不知道子查询将选择的用户,也不会达到3,000行的最大值? 为什么这么大的估计? 问题在于,这个较大的估算值随后会影响较大查询中的另一个联接以执行扫描而不是查找。 如果我使用子查询运行较大的查询,则需要1分40秒。 如果使用1155硬编码运行它,则需要2秒钟。 这对我来说很不寻常...

谢谢,

克里斯

优化器会尽力而为,但是统计数据和行数估计值到目前为止(您所看到的)还远远不够。

我假设您没有子查询就不能轻易将您更复杂的查询重写为联接。 如果可以的话,您应该先尝试一下。

如果失败了,该是时候使用关于数据性质的其他知识来通过提示帮助优化器了。 具体查看index提示中的forceseek选项。 请注意,如果以后更改数据,这可能很不好,所以请注意。

你有尝试过吗?

SELECT lt.user
FROM Users u
     INNER JOIN largeTable lt
        ON u.User = lt.User
WHERE u.externalId = 100

请查看以下内容: subqueries-vs-joins

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM