【问题标题】:improve query below row_number() over (partition by改进 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的数据类型是什么?它看起来像是日期或时间戳,但您使用字符串对其进行过滤。

标签: sql oracle window-functions


【解决方案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;

根据您的索引,这可能是最快的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    • 2020-01-14
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多