绝对没有SQL中的tstamp周围的函数?每小时历史数据查询

时间:2013-05-08 19:44:30

标签: sql performance oracle timestamp

我需要获取某个特定工作日的特定小时数据,直到10周。我工作的DB是Oracle。我想出了以下关于时间戳字段的条件:

TO_CHAR(hy.tstamp,'HH24')='10' 
AND hy.tstamp > sysdate - 70  
AND mod(extract ( day from sysdate-1) - extract ( day from hy.tstamp), 7) =0 

有人告诉我“绝对没有围绕tstamp的功能”(出于性能原因?)。如何在时间戳字段中指定没有操作的条件?

2 个答案:

答案 0 :(得分:4)

这听起来像抱怨性能的人从未听说过基于功能的索引。

Create index char_hy_stamp on my_table(to_char(hy.tstamp,'HH24'));

这应该避免全表扫描,这无疑是解释计划的一部分。一旦你获得了sqlfiddle功能,我们就可以从那里开始。

答案 1 :(得分:2)

如果您加入可接受范围的表,则可以过滤掉没有函数或函数索引的时间片。您可以像这样动态创建一个(请注意,您需要创建表的函数,但之后不需要它们):

SELECT
  TRUNC(SYSDATE + 6) - (7 * LEVEL) + INTERVAL '10' HOUR AS StartAt,
  TRUNC(SYSDATE + 6) - (7 * LEVEL) + INTERVAL '11' HOUR AS EndAt
FROM DUAL
CONNECT BY LEVEL <= 10

今天的日期是2013年5月8日,这将为您提供以下内容:

STARTAT             ENDAT
------------------- -------------------
05/07/2013 10:00:00 05/07/2013 11:00:00
04/30/2013 10:00:00 04/30/2013 11:00:00
04/23/2013 10:00:00 04/23/2013 11:00:00
04/16/2013 10:00:00 04/16/2013 11:00:00
04/09/2013 10:00:00 04/09/2013 11:00:00
04/02/2013 10:00:00 04/02/2013 11:00:00
03/26/2013 10:00:00 03/26/2013 11:00:00
03/19/2013 10:00:00 03/19/2013 11:00:00
03/12/2013 10:00:00 03/12/2013 11:00:00
03/05/2013 10:00:00 03/05/2013 11:00:00

现在只需将其加入您的查询即可获得所需的时间片,并注意您不需要函数:

WITH TimeRanges AS (
  SELECT
    TRUNC(SYSDATE + 6) - (7 * LEVEL) + INTERVAL '10' HOUR AS StartAt,
    TRUNC(SYSDATE + 6) - (7 * LEVEL) + INTERVAL '11' HOUR AS EndAt
  FROM DUAL
  CONNECT BY LEVEL <= 10
)
SELECT
  ... whatever ...
FROM your_table hy
INNER JOIN TimeRanges ON
  hy.tstamp >= TimeRanges.StartAt AND
  hy.tstamp < TimeRanges.EndAt

如果您的数据库人员了解对时间戳功能的过滤会导致性能下降(除非Woot4Moo指出,他们实现了功能索引),他们会理解用于创建时间表表的函数不会影响较大的查询