Mam tabelę w bazie danych Oracle. Schemat jest(self) łączyć w odstępach czasowych
create table PERIODS
(
ID NUMBER,
STARTTIME TIMESTAMP,
ENDTIME TIMESTAMP,
TYPE VARCHAR2(100)
)
Mam dwa różne TYPE's
: TYPEA
i TYPEB
. Mają niezależne czasy rozpoczęcia i zakończenia i mogą się nakładać. Co chciałbym znaleźć, to okresy TYPEB
, które rozpoczęły się, są całkowicie zamknięte lub zakończone w danym okresie TYPEA
.
Oto co wymyśliłem tej pory (z kilkoma przykładowymi danymi)
WITH mydata
AS (SELECT 100 ID,
To_timestamp('2015-08-01 11:00', 'YYYY-MM-DD HH24:MI') STARTTIME,
To_timestamp('2015-08-01 11:20', 'YYYY-MM-DD HH24:MI') ENDTIME,
'TYPEA' TYPE
FROM dual
UNION ALL
SELECT 110 ID,
To_timestamp('2015-08-01 11:30', 'YYYY-MM-DD HH24:MI') STARTTIME,
To_timestamp('2015-08-01 11:50', 'YYYY-MM-DD HH24:MI') ENDTIME,
'TYPEA' TYPE
FROM dual
UNION ALL
SELECT 120 ID,
To_timestamp('2015-08-01 12:00', 'YYYY-MM-DD HH24:MI') STARTTIME,
To_timestamp('2015-08-01 12:20', 'YYYY-MM-DD HH24:MI') ENDTIME,
'TYPEA' TYPE
FROM dual
UNION ALL
SELECT 105 ID,
To_timestamp('2015-08-01 10:55', 'YYYY-MM-DD HH24:MI') STARTTIME,
To_timestamp('2015-08-01 11:05', 'YYYY-MM-DD HH24:MI') ENDTIME,
'TYPEB' TYPE
FROM dual
UNION ALL
SELECT 108 ID,
To_timestamp('2015-08-01 11:05', 'YYYY-MM-DD HH24:MI') STARTTIME,
To_timestamp('2015-08-01 11:15', 'YYYY-MM-DD HH24:MI') ENDTIME,
'TYPEB' TYPE
FROM dual
UNION ALL
SELECT 111 ID,
To_timestamp('2015-08-01 11:15', 'YYYY-MM-DD HH24:MI') STARTTIME,
To_timestamp('2015-08-01 12:25', 'YYYY-MM-DD HH24:MI') ENDTIME,
'TYPEB' TYPE
FROM dual),
typeas
AS (SELECT starttime,
endtime
FROM mydata
WHERE TYPE = 'TYPEA'),
typebs
AS (SELECT id,
starttime,
endtime
FROM mydata
WHERE TYPE = 'TYPEB')
SELECT id
FROM typebs b
join typeas a
ON (b.starttime BETWEEN a.starttime AND a.endtime)
OR (b.starttime BETWEEN a.starttime AND a.endtime
AND b.endtime BETWEEN a.starttime AND a.endtime)
OR (b.endtime BETWEEN a.starttime AND a.endtime)
ORDER BY id;
To wydaje się działać na zasadzie, wynik z zapytania powyżej
ID
----------
105
108
111
więc wybiera trzy okresy TYPEB
, które rozpoczęły się lub zakończyły w ciągu pierwszego okresu TYPEA
.
Problem polega na tym, że tabela ma około 200 000 wpisów i już w tym rozmiarze powyższe zapytanie jest dość powolne --- co jest dla mnie bardzo zaskakujące, ponieważ liczba wpisów TYPEA
i jest dość niska (1-2 k)
Czy istnieje skuteczniejszy sposób wykonywania tego typu łączenia? Czy w moim zapytaniu brakuje mi czegoś innego?
tabela ma 200 000 wierszy, istnieją tylko dwie różne wartości typu "typ", ale każdy "typ" ma tylko 1000-2000 wierszy. Czy to oznacza, że ~ 196,000 wierszy w tabeli ma 'NULL' dla ich' type'? Jeśli zadasz pytanie dotyczące strojenia, możesz opublikować plan zapytania, który otrzymujesz i jakie indeksy są dostępne? –
Tabela ma 200 tys. Wierszy, z których większość ma typ, który nie ma dla mnie znaczenia dla tego zapytania. – Erik
@JustinCave to może być pytanie strojenia, ale być może jestem po prostu nieświadomy jakiejś innej funkcji, która uczyniłaby to zapytanie znacznie szybciej bez dostrajania. – Erik