2

tickets関連する 3 つの列を含む 1 つのテーブルがあります: id、where 、startおよびare 。finishstartfinishtimestamps

intervals関連する列が 1 つだけの 2 番目のテーブル ( ) がありtime pointます。time_pointtimestampです。time_point常に 15 分ごとです。この 2 番目のテーブルの内容は次のとおりです。

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

最初のテーブル (チケット) には 400 万件のレコードがあります。2 番目には 96 レコードしかありません (24 * 4)。

開いているチケットの数を選択する必要がありますtime_point

次のクエリを書きました: (簡易版)

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

これは機能しますが、遅すぎます。問題は、両方のテーブル間に実際の結合がなく、すべての行に対して完全なテーブル スキャンが実行されることです。

ここでパフォーマンスを向上させるにはどうすればよいですか?

ありがとう!

編集: これは Oracle DB です。

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

これを高速化する 1 つの方法は、複合インデックスに終了列を含めて、その値をフェッチするためにテーブルから読み取る必要がないようにすることです。

                create index IX_Tickets on Tickets(start,finish)

PS Tickets.start にも単純なインデックスをドロップします。

PPS明確 8:00, 8:15にしてください:あなたのintervals表にはtimestampデータ型ではありません。簡単にするために、質問の日付要素を削除しましたか?

于 2013-07-29T11:28:13.870 に答える