2013-07-29 51 views
2

我有一個包含三個相關的列tickets一個表:idstartfinish其中startfinishtimestampsquering的時候,SQL性能間隔

我有第二張表(intervals)只有一個相關的列是time pointtime_point也是timestamptime_point總是每15分鐘一班。這是第二張表的內容是:

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

第一張表(票)有4百萬記錄。第二個只有96個記錄(24 * 4)。

我必須選擇多少張門票在任何time_point

我寫了下面的查詢是開放的:(簡體版)

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

其作品,但實在是太慢了。問題是兩個表之間沒有真正的連接,我認爲每行都會執行全表掃描。

我該如何在這裏獲得更好的表現?

謝謝!

編輯:這是一個Oracle數據庫。加快這

+0

我懷疑,這個查詢在各種情況下工作。 'start

+1

如果你真的需要簡單的(可計算的)時間間隔,則應該將「完成」截斷到第一個早期的15分鐘標記。如果您需要更通用的方法,我會嘗試使用區間表來說明區間的開始和結束,並加入'ticket.finish> = interval.start和ticket.finish

+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 ; 
0

一種方法是包括在一個綜合指數結束列,因此沒有必要從表中讀取來獲取該值:

   create index IX_Tickets on Tickets(start,finish) 

附:刪除Tickets.start中的任何簡單索引。

P.P.S.請澄清:您的intervals表中的8:00, 8:15表不是timestamp數據類型。爲了簡單起見,你是否在你的問題中排除了日期元素?

+0

是的,我做到了。這是表格和查詢的簡化版本。 – Luixv

+0

不要「簡化」查詢。如果Ticket.start實際上是一個包含日期和時間塊的時間戳,則爲您指定的日期時間範圍創建一個包含日期元素(使用CTE,如果可用)的實際時間表的表格,然後將這些時間段與Ticket.start和Ticket.finish。綜合指數將有所幫助。 – Tim