首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取第N个最近业务日期-使用两种不同方法的查询性能非常不同

获取第N个最近业务日期-使用两种不同方法的查询性能非常不同
EN

Stack Overflow用户
提问于 2009-12-15 00:43:13
回答 3查看 346关注 0票数 2

我需要在T-5的基础上获得txns。这意味着我需要“回去”5个工作日。

我为此编写了两个SQL查询,第二种方法比第一种方法慢5倍。

怎么会这样?

代码语言:javascript
复制
-- Fast
with
BizDays as
( select top 5 bdate bdate
  from  dbo.business_days 
  where bdate < '20091211'
order by bdate Desc
)
,BizDate as ( select min(bdate) bdate  from BizDays)
select t.* from txns t
join BizDate on t.bdate <= BizDate.bdate

-- Slow
with
BizDays as
( select dense_rank() Over(order by bdate Desc) RN
        , bdate
  from  dbo.business_days 
  where bdate < '20091211'
)
,BizDate as ( select bdate from BizDays where RN = 5)
select t.* from txns t 
join BizDate on t.bdate <= BizDate.bdate
EN

回答 3

Stack Overflow用户

发布于 2009-12-15 00:44:39

DENSE_RANK不会像TOP 5那样在第一个5记录之后停止。

尽管DENSE_RANK是单调的,因此理论上可以优化为TOP WITH TIES,但SQL Server的优化器并不知道这一点,也不会进行这种优化。

如果您的工作日是独一无二的,您可以将DENSE_RANK替换为ROW_NUMBER并获得相同的性能,因为ROW_NUMBER针对TOP进行了优化。

票数 3
EN

Stack Overflow用户

发布于 2009-12-15 01:00:48

您是否可以先对会议数据使用ORDER BY,然后使用LIMIT offset, rowcount,而不是将条件放在where和join子句中

票数 0
EN

Stack Overflow用户

发布于 2009-12-15 04:29:15

运行速度如此之慢的原因是DENSE_RANK()ROW_NUMBER()是函数。引擎必须读取表中与WHERE子句匹配的每条记录,将函数应用于每一行,保存函数值,然后从该列表中获取前5个记录。

“普通”TOP5使用表上的索引来获取满足WHERE子句的前5条记录。在最好的情况下,引擎可能只需要读取几个索引页。最坏的情况是,它可能还必须读取一些数据页。即使没有索引,引擎也会读取行,但不必执行函数或处理临时表。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1902009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档