次のクエリを最適化しようとしています。
SELECT tickstime AS time,
quantity1 AS turnover
FROM cockpit_test.ticks
WHERE date_id BETWEEN 20111104 AND 20111109
AND mdc_id IN (297613)
ORDER BY time;
とてもシンプルですが、実行には約 60 ~ 90 秒かかります。cockpit_test.TICKSテーブルに 100M を超える行が含まれています。また、 MDC_ID列とDATE_ID列による索引もあります。
EXPLAIN PLAN は次の出力を提供します
"-------------------------------------------------------------------------------------------------------"
"| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |"
"-------------------------------------------------------------------------------------------------------"
"| 0 | SELECT STATEMENT | | 26905 | 604K| | 11783 (1)| 00:02:22 |"
"| 1 | SORT ORDER BY | | 26905 | 604K| 968K| 11783 (1)| 00:02:22 |"
"| 2 | TABLE ACCESS BY INDEX ROWID| TICKS | 26905 | 604K| | 11596 (1)| 00:02:20 |"
"|* 3 | INDEX RANGE SCAN | TICKS_MDC_DATE | 26905 | | | 89 (0)| 00:00:02 |"
"-------------------------------------------------------------------------------------------------------"
" "
"Predicate Information (identified by operation id):"
"---------------------------------------------------"
" "
" 3 - access(""MDC_ID""=297613 AND ""DATE_ID"">=20111104 AND ""DATE_ID""<=20111109)"
したがって、それが何を意味するのか完全にはわかりませんが、インデックスがヒットしているようで、ほとんどの時間はインデックス行 ID によって行にアクセスすることによって消費されています。
このクエリをより高速に実行する方法はありますか?
UPD
テーブル定義は次のとおりです。
Name Null? Type
----------------------------------------- -------- ----------------------------
DATE_ID NOT NULL NUMBER(38)
MDC_ID NOT NULL NUMBER(38)
TICKSTIME NOT NULL DATE
STATE NOT NULL NUMBER(38)
VALUE1 NOT NULL FLOAT(126)
VALUE2 FLOAT(126)
VOLUME1 FLOAT(126)
VOLUME2 FLOAT(126)
QUANTITY1 NUMBER(38)
QUANTITY2 NUMBER(38)
テーブルには 3 つのインデックスがあります。
- MDC_ID のインデックス
- DATE_ID、MDC_ID、TICKSTIME の複合インデックス
- DATE_ID、MDC_ID の複合インデックス