1

我在 Oracle 数据库中有一个表,其中包含一个时间戳列 nextTime 和一个字符串列 destName。还有更多列,但在这种情况下只有这两个是相关的。我正在尝试设计一个查询,该查询将返回具有特定间隔内的 nextTime 的不同 destName,并且返回的行数最多应为一千。当间隔内有超过一千个不同的 destName 时,我希望查询返回一千行,不多也不少。

我实际上有一个正在运行的查询,但它太慢了:

select destName 
from (select /*+ index(tblDestNames tbldestnames_destname)*/ distinct destName
from (select /*+ index(tblDestNames tbldestnames_nextTime)*/ destName
from tblDestNames 
where nextTime < :1 and nextTime >= :2 and destName is not null)) 
where rownum <= 1000; 

非常感谢有关如何设计更智能的查询或如何优化现有查询的任何想法。

4

2 回答 2

7

我不确定是否有理由不将查询简化为:

select destName 
from (
    select distinct destName
    from tblDestNames 
    where nextTime < :1 and nextTime >= :2 and destName is not null
    )
where rownum <= 1000; 

但是,这不会解决您的性能问题。问题是这样的:

where rownum <= 1000

通过将 rownum 替换为 'rank' 和 'over' 你会得到类似的东西:

select distinct destName
from (
    select
       destName
    from
       (select destName, rank()
        over (order by destName desc ) rnk
        from tblDestNames
        where nextTime < :1 and nextTime >= :2 and destName is not null) 
    where rnk <= 1000;
    )

好处是,通过“结束”,您可以选择将显示的结果和不显示的结果的顺序。

编辑:实际上它可以进一步简化为:

select
   distinct destName
from
   (select destName, rank()
    over (order by destName desc ) rnk
    from tblDestNames
    where nextTime < :1 and nextTime >= :2 and destName is not null) 
where rnk <= 1000;
于 2011-08-10T08:50:14.243 回答
1

我捡到的东西

  1. 你应该把执行计划优化留给 RDBMS,除非你真的知道得更好
  2. 无需从最里面的子查询返回重复的名称

语义略有不同的更简单查询:

SELECT destName
FROM (SELECT DISTINCT destName
      FROM tblDestNames
      WHERE destName IS NOT NULL 
        AND nextTime NOT BETWEEN :1 and :2)
WHERE rownum <= 1000;

请注意,它BETWEEN是包容性的,即x BETWEEN y AND z等于y <= x <= z。要排除上限,您要么必须按照您的方式进行操作,要么将参数 :2 减少一个单位 nextTime 。

于 2011-08-10T08:49:13.020 回答