我需要在T-5的基础上获得txns。这意味着我需要“回去”5个工作日。
我为此编写了两个SQL查询,第二种方法比第一种方法慢5倍。
怎么会这样?
-- 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发布于 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进行了优化。
发布于 2009-12-15 01:00:48
您是否可以先对会议数据使用ORDER BY,然后使用LIMIT offset, rowcount,而不是将条件放在where和join子句中
发布于 2009-12-15 04:29:15
运行速度如此之慢的原因是DENSE_RANK()和ROW_NUMBER()是函数。引擎必须读取表中与WHERE子句匹配的每条记录,将函数应用于每一行,保存函数值,然后从该列表中获取前5个记录。
“普通”TOP5使用表上的索引来获取满足WHERE子句的前5条记录。在最好的情况下,引擎可能只需要读取几个索引页。最坏的情况是,它可能还必须读取一些数据页。即使没有索引,引擎也会读取行,但不必执行函数或处理临时表。
https://stackoverflow.com/questions/1902009
复制相似问题