查询语句如下:
select top 100 u.*, row_number() over(order by u.CreatedTime DESC ) n from MpUsers as u
where AccountId ='28C64BCC-48A2-48BD-855A-AD2434E40000'
其中AccountId 是索引列,整个表120万条数据。
奇怪的是:
1、如果CreatedTime 字段不加索引,查询在1秒内返回;
2、如果CreatedTime 字段加了索引,查询在4分钟左右;
3、如果加AccountId和CreatedTime 组合索引,查询在1秒内返回。
哪位那牛能解释下为什么吗?
既然用了 TOP
,就没必要用 row_number() over
,改为下面的试试
select top 100 u.*
from MpUsers as u
where AccountId ='28C64BCC-48A2-48BD-855A-AD2434E40000'
order by u.CreatedTime DESC
这个sql只是为了测试,使用rownumber是为了分页。
没有执行计划的sql语句性能分析都是耍流氓
谢谢反馈
后面通过分析发现是加了createdTime字段索引后,执行计划在createdTime这步执行了index-scan,返回28万条数据, 这个开销最大。不知道为啥会出现这样的情况。
另一个奇怪的现象是,我们总共有4个一模一样的数据库,表结构一模一样,数据量不一样。但只有这一个数据库是因为加了createdTime索引变得更慢,其他3个数据库都是加了createdTime索引变得快几百倍。其他3个数据量分别为:120万、70万、60万。
这4个数据库实际执行计划都一模一样,就是第一个index-scan返回28万数据,其他3个都返回正常的几百条数据。这是唯一的区别,也是最终导致奇怪结果的唯一原因。
他们的预估行数一样吗,直方图一样吗?
@czd890: 预估执行计划差不多,但是第一个异常数据库的实际执行计划与预估执行计划差别太大。预估很少,实际却28万。猜测是表统计信息缓存所致。不过后面没有去继续研究了。