。私は私にはないものを動作するようになっていると何この時点で困惑していると思うのOracleインデックスの行動についての詳細を学ぶました。オラクル:私は過去2日間に渡って効率的にこのクエリの作業を取得しようとしてきた最適化二回自己結合クエリ
基本的に、クエリは値を合計し、昨日と先週の値と比較しています。
私はそれを分解して遊んだ、私は私の心の分析クエリとインデックスの順序を変更するおもしろいが何も動作するようだ。すべての私のテストはすぐに私はそれだけで永遠にかかる20万行をテーブルの上にそれを実行するよう、500Kの行を持つテーブルにされています。
ご協力いただきまして誠にありがとうございます。
元の投稿を修正しました。 :)
CREATE TABLE TABLE_1
(ORDER_LINE_ID NUMBER, OFFSET NUMBER, BREAK_ID NUMBER, ZONE NUMBER, NETWORK NUMBER, HOUR_OF_DAY NUMBER, START_TIME DATE, END_TIME DATE, SUCCESS NUMBER
CONSTRAINT "TABLE_1_PK" PRIMARY KEY (ORDER_LINE_ID, OFFSET, BREAK_ID, ZONE, HOUR_OF_DAY))
-- SUCCESS is already aggregated during the insert
-- These are last week's records
INSERT INTO TABLE_1 (ORDER_LINE_ID, OFFSET, BREAK_ID, ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME, SUCCESS)
VALUES (1,0,1, 1, 1, 2016042001,'04/20/2016 00:00:00', '04/20/2016 02:00:00', 1);
INSERT INTO TABLE_1 (ORDER_LINE_ID, OFFSET, BREAK_ID, ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME, SUCCESS)
VALUES (1,30,1, 1, 1, 2016042001,'04/20/2016 00:00:00', '04/20/2016 02:00:00', 2);
INSERT INTO TABLE_1 (ORDER_LINE_ID, OFFSET, BREAK_ID, ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME, SUCCESS)
VALUES (2,0,1, 1, 1, 2016042001,'04/20/2016 00:00:00', '04/20/2016 02:00:00', 1);
INSERT INTO TABLE_1 (ORDER_LINE_ID, OFFSET, BREAK_ID, ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME, SUCCESS)
VALUES (2,30,1, 1, 1, 2016042001,'04/20/2016 00:00:00', '04/20/2016 02:00:00', 1);
-- These are yesterday's records
INSERT INTO TABLE_1 (ORDER_LINE_ID, OFFSET, BREAK_ID, ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME, SUCCESS)
VALUES (3,0,1, 1, 1, 2016042601,'04/26/2016 00:00:00', '04/26/2016 02:00:00', 1);
INSERT INTO TABLE_1 (ORDER_LINE_ID, OFFSET, BREAK_ID, ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME, SUCCESS)
VALUES (3,30,1, 1, 1, 2016042601,'04/26/2016 00:00:00', '04/26/2016 02:00:00', 2);
INSERT INTO TABLE_1 (ORDER_LINE_ID, OFFSET, BREAK_ID, ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME, SUCCESS)
VALUES (4,0,1, 1, 1, 2016042601,'04/26/2016 00:00:00', '04/26/2016 02:00:00', 1);
INSERT INTO TABLE_1 (ORDER_LINE_ID, OFFSET, BREAK_ID, ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME, SUCCESS)
VALUES (4,30,1, 1, 1, 2016042601,'04/26/2016 00:00:00', '04/26/2016 02:00:00', 1);
-- This is today's records
INSERT INTO TABLE_1 (ORDER_LINE_ID, OFFSET, BREAK_ID, ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME, SUCCESS)
VALUES (5,0,1, 1, 1, 2016042701,'04/27/2016 00:00:00', '04/27/2016 02:00:00', 1);
INSERT INTO TABLE_1 (ORDER_LINE_ID, OFFSET, BREAK_ID, ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME, SUCCESS)
VALUES (5,30,1, 1, 1, 2016042701,'04/27/2016 00:00:00', '04/27/2016 02:00:00', 1);
-- Original twice join query
SELECT BREAK_ID, ORDER_LINE_ID, HOUR_OF_DAY, OFFSET, ZONE, NETWORK, START_TIME, END_TIME, SUM(SUCCESS), SUM(YESTERDAY_SUCCESS), SUM(LAST_WEEK_SUCCESS)
FROM TABLE_1 CURRENT_DAY
LEFT OUTER JOIN (
SELECT SUM(SUCCESS) YESTERDAY_SUCCESS, ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME FROM TABLE_1
GROUP BY ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME
) YESTERDAY
ON YESTERDAY.START_TIME + 1 = CURRENT_DAY.START_TIME
AND YESTERDAY.END_TIME + 1 = CURRENT_DAY.END_TIME
AND YESTERDAY.HOUR_OF_DAY = CURRENT_DAY.HOUR_OF_DAY
AND YESTERDAY.NETWORK = CURRENT_DAY.NETWORK
AND YESTERDAY.ZONE = CURRENT_DAY.ZONE
LEFT OUTER JOIN (
SELECT SUM(SUCCESS) LAST_WEEK_SUCCESS, ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME FROM TABLE_1
GROUP BY ZONE, NETWORK, HOUR_OF_DAY, START_TIME, END_TIME
) LAST_WEEK
ON YESTERDAY.START_TIME + 7 = CURRENT_DAY.START_TIME
AND YESTERDAY.END_TIME + 7 = CURRENT_DAY.END_TIME
AND YESTERDAY.HOUR_OF_DAY = CURRENT_DAY.HOUR_OF_DAY
AND YESTERDAY.NETWORK = CURRENT_DAY.NETWORK
AND YESTERDAY.ZONE = CURRENT_DAY.ZONE
GROUP BY BREAK_ID, ORDER_LINE_ID, HOUR_OF_DAY, OFFSET, ZONE, NETWORK, START_TIME, END_TIME;
-- Using Analytic Query (thank you to MT0)
SELECT BREAK_ID, ORDER_LINE_ID, HOUR_OF_DAY, OFFSET, ZONE, NETWORK, START_TIME, END_TIME, SUM(SUCCESS), SUM(YESTERDAY_SUCCESS), SUM(LAST_WEEK_SUCCESS)
FROM (
SUM(SUCCESS)
OVER (PARTITION BY ZONE, NETWORK, HOUR_OF_DAY, TO_CHAR(START_TIME, 'HH24:MI:SS'), TO_CHAR(END_TIME, 'HH24:MI:SS')
ORDER BY START_TIME
RANGE BETWEEN INTERVAL '1' DAY PRECDEDING AND INTERVAL '1' DAY PRECEDING
) AS YESTERDAY_SUCCESS,
SUM (SUCCESS)
OVER (PARTITION BY ZONE, NETWORK, HOUR_OF_DAY, TO_CHAR(START_TIME, 'HH24:MI:SS'), TO_CHAR(END_TIME, 'HH24:MI:SS')
ORDER BY START_TIME
RANGE BETWEEN INTERVAL '7' DAY PRECDEDING AND INTERVAL '7' DAY PRECEDING
) AS LAST_WEEK_SUCCESS
FROM TABLE_1
) T1
WHERE SYSDATE - INTERVAL '12' HOUR <= START_TIME
AND START_TIME < SYSDATE - INTERVAL '1' HOUR
GROUP BY BREAK_ID, ORDER_LINE_ID, HOUR_OF_DAY, OFFSET, ZONE, NETWORK, START_TIME, END_TIME;
私は、この質問を私が理解しやすいものにする助けに感謝しなければならない。すべてが期待どおりに機能しますが、パフォーマンスにはチューニングが使用される可能性があります。
2000万行
とテーブルの上に500K行
400秒とテーブルの上に1.8秒私は、Oracleが提供するいくつかの実行計画を追加したいです。パフォーマンスのチューニングに問題があります。
-- using twice self join
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | Writes | OMem | 1Mem | O/1/M |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 50 |00:00:00.84 | 99875 | 217 | 1705 | | | |
| 1 | HASH GROUP BY | | 1 | 6711 | 50 |00:00:00.84 | 99875 | 217 | 1705 | 1616K| 995K| |
|* 2 | FILTER | | 1 | | 119K|00:00:00.65 | 99875 | 0 | 0 | | | |
| 3 | NESTED LOOPS OUTER | | 1 | 54M| 119K|00:00:00.64 | 99875 | 0 | 0 | | | |
|* 4 | HASH JOIN OUTER | | 1 | 109 | 119K|00:00:00.52 | 99875 | 0 | 0 | 13M| 2093K| 1/0/0|
| 5 | TABLE ACCESS BY INDEX ROWID| TABLE_1_IDX | 1 | 109 | 119K|00:00:00.14 | 85908 | 0 | 0 | | | |
|* 6 | INDEX RANGE SCAN | START_TIME_IDX | 1 | 109 | 119K|00:00:00.02 | 320 | 0 | 0 | | | |
| 7 | VIEW | | 1 | 1250 | 29311 |00:00:00.23 | 13967 | 0 | 0 | | | |
| 8 | HASH GROUP BY | | 1 | 1250 | 29311 |00:00:00.22 | 13967 | 0 | 0 | 3008K| 1094K| 1/0/0|
|* 9 | FILTER | | 1 | | 88627 |00:00:00.20 | 13967 | 0 | 0 | | | |
|* 10 | TABLE ACCESS FULL | TABLE_1 | 1 | 1250 | 88627 |00:00:00.19 | 13967 | 0 | 0 | | | |
| 11 | VIEW | | 119K| 499K| 0 |00:00:00.10 | 0 | 0 | 0 | | | |
| 12 | SORT GROUP BY | | 119K| 499K| 0 |00:00:00.08 | 0 | 0 | 0 | 1024 | 1024 | 1/0/0|
|* 13 | FILTER | | 119K| | 0 |00:00:00.02 | 0 | 0 | 0 | | | |
| 14 | TABLE ACCESS FULL | TABLE_1 | 0 | 499K| 0 |00:00:00.01 | 0 | 0 | 0 | | | |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter([email protected]!-17<[email protected]!-16)
4 - access("YESTERDAY"."ZONE"="T1"."ZONE" AND "YESTERDAY"."NETWORK"="T1"."NETWORK" AND "YESTERDAY"."HOUR_OF_DAY"="T1"."HOUR_OF_DAY"
AND "T1"."END_TIME"=INTERNAL_FUNCTION("YESTERDAY"."END_TIME")+1 AND
"T1"."START_TIME"=INTERNAL_FUNCTION("YESTERDAY"."START_TIME")+1)
6 - access("T1"."START_TIME">[email protected]!-17 AND "T1"."START_TIME"<[email protected]!-16)
9 - filter([email protected]!-17<[email protected]!-16)
10 - filter((INTERNAL_FUNCTION("START_TIME")+1>[email protected]!-17 AND INTERNAL_FUNCTION("START_TIME")+1<[email protected]!-16))
13 - filter(("YESTERDAY"."ZONE"="T1"."ZONE" AND "YESTERDAY"."NETWORK"="T1"."NETWORK" AND "YESTERDAY"."HOUR_OF_DAY"="T1"."HOUR_OF_DAY"
AND "T1"."END_TIME"=INTERNAL_FUNCTION("YESTERDAY"."END_TIME")+7 AND
"T1"."START_TIME"=INTERNAL_FUNCTION("YESTERDAY"."START_TIME")+7))
分析クエリを使用して別の実行計画あなたが見ることができるように、私はからクエリの利点を自己参加のstart_timeにインデックスを追加しましたが、実績はオフになっている対推定
-- using analytic query
-------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | O/1/M |
-------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 50 |00:00:01.51 | 13967 | | | |
| 1 | HASH GROUP BY | | 1 | 499K| 50 |00:00:01.51 | 13967 | 98M| 7788K| |
|* 2 | VIEW | | 1 | 499K| 119K|00:00:01.15 | 13967 | | | |
| 3 | WINDOW SORT | | 1 | 499K| 499K|00:00:01.43 | 13967 | 66M| 2823K| 1/0/0|
|* 4 | FILTER | | 1 | | 499K|00:00:00.16 | 13967 | | | |
| 5 | TABLE ACCESS FULL| TABLE_1 | 1 | 499K| 499K|00:00:00.12 | 13967 | | | |
-------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("T1"."START_TIME">[email protected]!-INTERVAL'+17 00:00:00' DAY(2) TO SECOND(0) AND
"T1"."START_TIME"<[email protected]!-INTERVAL'+16 00:00:00' DAY(2) TO SECOND(0)))
4 - filter([email protected]!-INTERVAL'+17 00:00:00' DAY(2) TO SECOND(0)<[email protected]!-INTERVAL'+16 00:00:00' DAY(2) TO
SECOND(0))
(MT0にもう一度感謝を) 。分析クエリは、インデックスとは何も関係がないと判断するだけです。すべてのアイデア、参考点、または助けをいただければ幸いです。事前に感謝、誰もが。
あなたがしようとしていることを説明するのに役立つサンプルデータを投稿できますか? 'field_6'と' field_7'の日付は時間なしであるのですか、それとも時間の成分があり、同じグループ内に複数の値がありますか? – MT0
あなたは 'field_6'と' field_7'に外部結合しています - あなたは昨日と先週の結合がフィールド1,2、および3(グループ化しています)と同じ値を持っていることをどのように知っていますか? – MT0
MT0、お返事ありがとうございます。より現実的なフィールド名を表示するようにクエリを修正しました。私もタイプを指定しました。ご協力いただきありがとうございます。 – OneClutteredMind