改进 row_number() 下的查询 over (partition by
Posted
技术标签:
【中文标题】改进 row_number() 下的查询 over (partition by【英文标题】:improve query below row_number() over (partition by 【发布时间】:2016-11-11 05:53:34 【问题描述】:有什么方法可以改进下面的查询,当我只检查一条记录时,它的工作速度更快(NAME='T 104'),但是对于没有 NAME='T 104' 的所有现有(113 条记录)记录,它需要大约5 秒:
下面的一个需要 73 毫秒:
select
name, PRODUCTION_DAY, daytime
from
(select
name, PRODUCTION_DAY, daytime,
row_number() over (partition by name order by daytime desc) as seqnum
from
RESULT_1 t
where
PRODUCTION_DAY < '15-May-2015'
)
where
seqnum = 1 and NAME = 'T 104'
下面的需要 4 秒:
select
name, PRODUCTION_DAY, daytime
from
(select
name, PRODUCTION_DAY, daytime,
row_number() over (partition by name order by daytime desc) as seqnum
from
RESULT_1 t
where
PRODUCTION_DAY < '15-May-2015'
)
where
seqnum = 1
谢谢, S
【问题讨论】:
您能否分别显示两个查询以及它们的运行时间? 查看更新的查询 你能在这两个查询上运行EXPLAIN
吗?对于您的观察,我没有看到明显的答案。
请edit您的问题添加两个语句的执行计划。 Formatted 文本 请no screen shots
production_day的数据类型是什么?它看起来像是日期或时间戳,但您使用字符串对其进行过滤。
【参考方案1】:
在“名称”列上添加索引
这两个查询的区别在于 where 子句中多了一个谓词。
您也可以尝试在派生表中按名称放置过滤器
select
name, PRODUCTION_DAY, daytime
from
(select
name, PRODUCTION_DAY, daytime,
row_number() over (partition by name order by daytime desc) as seqnum
from
RESULT_1 t
where
PRODUCTION_DAY < '15-May-2015'
and NAME = 'T 104'
)
where
seqnum = 1
【讨论】:
嗯,我看错了这个问题。你有白天的索引吗?【参考方案2】:我认为当你像这样重写查询时应该得到相同的结果:
SELECT NAME,
MAX(PRODUCTION_DAY) KEEP (DENSE_RANK FIRST ORDER BY daytime) AS PRODUCTION_DAY,
MIN(daytime) AS daytime
FROM RESULT_1
WHERE PRODUCTION_DAY < '15-May-2015'
AND NAME = 'T 104'
GROUP BY NAME;
根据您的索引,这可能是最快的方法。
【讨论】:
以上是关于改进 row_number() 下的查询 over (partition by的主要内容,如果未能解决你的问题,请参考以下文章
分页查询的两种方法(双top 双order 和 row_number() over ())
从重查询distictgroup和row_number() over
使用 Row_number() OVER(partition BY..) 以及声明局部变量
在 SQL Server 2005 中使用 ROW_NUMBER() OVER () 对不同列进行排序的分页查询