2

我有一张tickets包含三个相关列的表:id,startfinishwherestartfinishare timestamps

我有第二张表 ( intervals),其中只有一个相关列是time point. time_point也是一个timestamptime_point总是每 15 分钟一次。即第二个表的内容是:

8:00
8:15
8:30
...

第一个表(票证)有 400 万条记录。第二个只有 96 条记录 (24 * 4)。

我必须选择在任何时候有多少张票是开放的time_point

我写了以下查询:(简化版)

select * 
from interval, ticket 
where (finish is null or finish > time_point)
      and start < time_point

这有效,但太慢了。问题是两个表之间没有真正的连接,我假设对每一行都执行了全表扫描。

我怎样才能在这里获得更好的性能?

谢谢!

编辑:这是一个 Oracle 数据库。

4

2 回答 2

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 ;
于 2013-07-29T13:27:04.847 回答
0

加快此速度的一种方法是将完成列包含在复合索引中,因此无需从表中读取以获取该值:

                create index IX_Tickets on Tickets(start,finish)

PS 也删除Tickets.start 上的任何简单索引。

PPS 请澄清: 8:00, 8:15在您的intervals表中不是timestamp数据类型。为了简单起见,您是否消除了问题中的日期元素?

于 2013-07-29T11:28:13.870 回答