我有历史表来存储决定性的可用性
该表有超过1000万行。
CREATE TABLE HIST_AVAILABLE_DISP
(
DISP VARCHAR2(100 BYTE),
STATUS CHAR(1 BYTE),
DATE_CHECK DATE
)
我的表格带有决定词:
CREATE TABLE DISPOSITIVE
(
ID INTEGER NOT NULL,
ID_TYPE INTEGER NOT NULL,
DISP VARCHAR2(100 BYTE),
........
)
我有一个例程来检查dispositive是否可用。
如果可用,我会插入一行DATE_CHECK = sysdate
和STATUS = 1
。如果不可用,我会插入一行"说我检查了dispositive但没有得到DATE_CHECK = sysdate
和STATUS = 0
的回复(也称为不可用),两个语句都在HIST_AVAILABLE_DISP
。< / p>
我需要获得超过24小时不可用的所有决定。 这是我做的:
SELECT 'Unavailable24h' type, id_type, disp
FROM (SELECT r.id_type, r.disp, MAX (h.DATE_CHECK) last_check,
last_availability, ROUND ((MAX (h.DATE_CHECK) - last_availability), 0) days_out
FROM HIST_AVAILABLE_DISP h
INNER JOIN
(SELECT disp, MAX (DATE_CHECK) last_availability
FROM HIST_AVAILABLE_DISP h
WHERE h.status = 1
GROUP BY disp) d ON (d.disp = h.disp)
INNER JOIN DISPOSITIVE r ON (h.disp = r.disp)
WHERE r.id_type IN (1, 2)
AND h.DATA > SYSDATE - 1
GROUP BY r.disp, r.id_type) t1
WHERE days_out * 24 > 24
重点是一次选择需要大约20秒......因为此查询会获取整个表格( 表格访问完整 ),正如我所说,它有超过1000万行。
有没有办法加快查询速度? 之后我需要的是检查过去365天(列表日 - 不可用的存款处数)中所有存款的可用性
修改
假设我只有两个决定(A和B):
并且正在执行select * from HIST_AVAILABLE_DISP
:
DISP STATUS DATE_CHECK
A 0 15/02/2016 00:00:00
A 1 17/02/2016 00:00:00
A 0 18/02/2016 00:00:00
A 0 18/02/2016 00:30:00
....
A 1 19/02/2016 00:00:00
我的输出是:
Day count_unavailable
16/02/2016 1
17/02/2016 0
18/02/2016 1
19/02/2016 0
解释平原:
SELECT STATEMENT ALL_ROWSCost: 16,545 Bytes: 153,66 Cardinality: 2,561
10 FILTER
9 HASH GROUP BY Cost: 16,545 Bytes: 153,66 Cardinality: 2,561
8 HASH JOIN Cost: 16,542 Bytes: 3.072.120 Cardinality: 51,202
3 VIEW USER. Cost: 9,527 Bytes: 15,929 Cardinality: 937
2 HASH GROUP BY Cost: 9,527 Bytes: 14,992 Cardinality: 937
1 TABLE ACCESS FULL TABLE USER.HIST_AVAILABLE_DISP Cost: 9,168 Bytes: 80.954.416 Cardinality: 5.059.651
7 HASH JOIN Cost: 7,014 Bytes: 2.201.686 Cardinality: 51,202
4 TABLE ACCESS FULL TABLE USER.DISPOSITIVE Cost: 7 Bytes: 24,612 Cardinality: 879
6 TABLE ACCESS BY INDEX ROWID TABLE USER.HIST_AVAILABLE_DISP Cost: 7,006 Bytes: 819,075 Cardinality: 54,605
5 INDEX RANGE SCAN INDEX USER.IDX_DATA Cost: 315 Cardinality: 54,605
谓词信息:
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(ROUND(MAX("H"."DATE_CHECK")-"D"."DATE_CHECK",0)*24>24)
3 - access("D"."DISP"="H"."DISP")
6 - filter(TO_NUMBER("H"."STATUS")=1)
7 - access("H"."DISP"="D"."DISP")
8 - filter("D"."KEY_TYPE"= 1 AND ("D"."ID_TYPE"=1 OR "D"."ID_TYPE"=2))
10 - access("H"."DATE_CHECK">SYSDATE@!-1)
答案 0 :(得分:0)
查询 - 获取过去24小时内无法使用的所有DISP
:
SELECT *
FROM DISPOSITIVE d
WHERE NOT EXISTS ( SELECT 'X'
FROM HIST_AVAILABLE_DISP h
WHERE STATUS = 1
AND DATE_CHECK > SYSDATE - 1
AND d.DISP = h.DISP );
查询 - 获取最后一个尚未提供但已被发现不可用的所有DISP
:
SELECT *
FROM DISPOSITIVE d
WHERE NOT EXISTS ( SELECT 'X'
FROM HIST_AVAILABLE_DISP h
WHERE STATUS = 1
AND DATE_CHECK > SYSDATE - 1
AND d.DISP = h.DISP )
AND EXISTS ( SELECT 'X'
FROM HIST_AVAILABLE_DISP h
WHERE STATUS = 0
AND DATE_CHECK > SYSDATE - 1
AND d.DISP = h.DISP );
查询 - 检查去年的每个24小时:
SELECT COLUMN_VALUE AS Start_of_24hr_period,
d.*
FROM DISPOSITIVE d
CROSS JOIN
TABLE(
CAST(
MULTISET(
SELECT ADD_MONTHS( SYSDATE, -12 ) + LEVEL
FROM DUAL
CONNECT BY ADD_MONTHS( SYSDATE, -12 ) + LEVEL <= SYSDATE
)
AS SYS.ODCIDATELIST
)
) y
WHERE NOT EXISTS ( SELECT 'X'
FROM HIST_AVAILABLE_DISP h
WHERE STATUS = 1
AND DATE_CHECK > y.COLUMN_VALUE - 1
AND DATE_CHECK <= y.COLUMN_VALUE
AND d.DISP = h.DISP )
AND EXISTS ( SELECT 'X'
FROM HIST_AVAILABLE_DISP h
WHERE STATUS = 0
AND DATE_CHECK > y.COLUMN_VALUE - 1
AND DATE_CHECK <= y.COLUMN_VALUE
AND d.DISP = h.DISP );
如果您想检查整天(而不是24小时),请更改:
SELECT ADD_MONTHS( SYSDATE, -12 ) + LEVEL
FROM DUAL
CONNECT BY ADD_MONTHS( SYSDATE, -12 ) + LEVEL <= SYSDATE
要:
SELECT ADD_MONTHS( TRUNC( SYSDATE ) + 1, -12 ) + LEVEL
FROM DUAL
CONNECT BY ADD_MONTHS( TRUNC( SYSDATE ) + 1, -12 ) + LEVEL <= TRUNC( SYSDATE ) + 1