我有一个tickets
的表,其中包含三个相关列:id
,start
和finish
其中start
和finish
为{{ 1}}。
我有第二个表(timestamps
),只有一个相关列intervals
。 time point
也是time_point
。 timestamp
总是每15分钟一次。这是第二个表的内容是:
time_point
第一张表(票证)有4百万条记录。第二个只有96条记录(24 * 4)。
我必须选择在任何8:00
8:15
8:30
...
我写了以下查询:(简化版)
time_point
哪个有效,但太慢了。问题是两个表之间没有真正的连接,我认为每行都要进行全表扫描。
我怎样才能在这里获得更好的表现?
谢谢!
编辑:这是一个Oracle数据库。
答案 0 :(得分:1)
我相信你不需要交叉加入或创建一个间隔表。 而是尝试以下:
> select count(*), tsd from (
> select
> /****************************************************************
> Now
> 1- bring your finish column into the format you need: HH24:MI
> 2- truncate its content down to the interval the row belongs to
> ****************************************************************/
> to_char(dt,'HH24')|| decode(trunc(to_char(dt,'MI')/15) * 15,0,'00',trunc(to_char(dt,'MI')/15)*15)
> tsd
> from (
> select nvl( finish ,to_date('31.12.2999', 'dd.mm.yyyy')) dt --
> from tickets
> /****************************************************************
> Now Filter out your tickets(before truncate), to find the relevant
> tickets for your period use a Parameter date and compare it to the
> start and end columns nvl( finish ,to_date('31.12.2999', dd.mm.yyyy'))
> ****************************************************************/
> where P_YOUR_PARAM_DATE between start
> and nvl( finish ,to_date('31.12.2999', 'dd.mm.yyyy'))
> ) dat
> ) group by tsd order by tsd ;
答案 1 :(得分:0)
加快这一步的一种方法是在复合索引中包含finish列,这样就无需从表中读取以获取该值:
create index IX_Tickets on Tickets(start,finish)
P.S。删除Tickets.start上的任何简单索引。
P.P.S。请澄清:8:00, 8:15
表中的intervals
不是timestamp
数据类型。为简单起见,您是否在问题中删除了日期元素?