改进 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 () 对不同列进行排序的分页查询

在 SQL Server 2005 中使用 ROW_NUMBER() OVER () 对不同列进行排序的分页查询

row_number() over(...)函数