使用SQL检索可用性历史

时间:2016-02-19 18:25:59

标签: sql oracle

我有历史表来存储决定性的可用性

该表有超过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 = sysdateSTATUS = 1。如果不可用,我会插入一行&#34;说我检查了dispositive但没有得到DATE_CHECK = sysdateSTATUS = 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)

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