Требуется объяснение для понимания кода SQL - PullRequest
0 голосов
/ 14 июня 2019

У нас есть вложенный SQL-код, который запрашивает данные о производительности из нескольких таблиц базы данных HANA.Нужна помощь, чтобы понять, как выполняется код

По этой ссылке можно узнать, как работает вложение: https://mode.com/sql-tutorial/sql-subqueries/

  SELECT
  START_TIME,
  BLK_PHASE_START_TIME,
  CRIT_PHASE_START_TIME,
  END_TIME,
  HOST,
  LPAD(PORT, 5) PORT,
  LPAD(NUM_SAVEPOINTS, 10) SAVEPOINTS,
  MAP(PURPOSE, 'DROP_SNAPSHOT', 'DS', 'NORMAL', 'N', 'SNAPSHOT_FOR_REPLICATION', 'SFR', 'SNAPSHOT_FOR_BACKUP', 'SFB', 'SNAPSHOT_FOR_RESUMERE...', 'SRR', 'SNAPSHOT_FOR_SECONDARY', 'SFS', PURPOSE) P,
  MAP(INITIATION, 'EXCECUTED_EXPLICITLY', 'E', 'EXECUTED_EXPLICITLY', 'E', 'TRIGGERED_TIMEBASED', 'T', INITIATION) I,
  LPAD(TO_DECIMAL(AVG_RETRIES, 10, 2), 11) AVG_RETRIES,
  LPAD(TO_DECIMAL(AVG_DURATION_S, 12, 2), 11) AVG_TOTAL_S,
  LPAD(TO_DECIMAL(AVG_BLOCKING_PHASE_S, 12, 2), 9)  AVG_BLK_S,
  LPAD(TO_DECIMAL(AVG_WAIT_FOR_LOCK_PHASE_S, 12, 2), 10) AVG_LOCK_S,
  LPAD(TO_DECIMAL(AVG_CRITICAL_PHASE_S, 12, 2), 10) AVG_CRIT_S,
  LPAD(TO_DECIMAL(ROUND(AVG_SIZE_MB), 11, 0), 11) AVG_SIZE_MB,
  LPAD(TO_DECIMAL(MB_PER_S, 10, 2), 8) MB_PER_S,
  LPAD(TO_DECIMAL(RS_SIZE_PCT, 12, 2), 11) RS_SIZE_PCT
FROM 
( SELECT
    CASE WHEN NUM_SAVEPOINTS = 1 THEN CRIT_PHASE_START_TIME ELSE 'various' END CRIT_PHASE_START_TIME,
    CASE WHEN NUM_SAVEPOINTS = 1 THEN BLK_PHASE_START_TIME ELSE 'various' END BLK_PHASE_START_TIME,
    CASE WHEN NUM_SAVEPOINTS = 1 THEN END_TIME ELSE 'various' END END_TIME,
    START_TIME,
    HOST,
    PORT,
    NUM_SAVEPOINTS,
    INITIATION,
    PURPOSE,
    AVG_RETRIES,
    AVG_DURATION_S,
    AVG_BLOCKING_PHASE_S,
    AVG_WAIT_FOR_LOCK_PHASE_S,
    AVG_CRITICAL_PHASE_S,
    AVG_SIZE_MB,
    MAP(SUM_DURATION_S, 0, 0, SUM_SIZE_MB / SUM_DURATION_S) MB_PER_S,
    RS_SIZE_PCT
  FROM
  ( SELECT
      CASE 
        WHEN BI.AGGREGATE_BY = 'NONE' OR INSTR(BI.AGGREGATE_BY, 'TIME') != 0 THEN 
          CASE 
            WHEN BI.TIME_AGGREGATE_BY LIKE 'TS%' THEN
              TO_VARCHAR(ADD_SECONDS(TO_TIMESTAMP('2014/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS'), FLOOR(SECONDS_BETWEEN(TO_TIMESTAMP('2014/01/01 00:00:00', 
              'YYYY/MM/DD HH24:MI:SS'), CASE BI.TIMEZONE WHEN 'UTC' THEN ADD_SECONDS(SP.START_TIME, SECONDS_BETWEEN(CURRENT_TIMESTAMP, CURRENT_UTCTIMESTAMP)) ELSE SP.START_TIME END) / SUBSTR(BI.TIME_AGGREGATE_BY, 3)) * SUBSTR(BI.TIME_AGGREGATE_BY, 3)), 'YYYY/MM/DD HH24:MI:SS')
            ELSE TO_VARCHAR(CASE BI.TIMEZONE WHEN 'UTC' THEN ADD_SECONDS(SP.START_TIME, SECONDS_BETWEEN(CURRENT_TIMESTAMP, CURRENT_UTCTIMESTAMP)) ELSE SP.START_TIME END, BI.TIME_AGGREGATE_BY)
          END
        ELSE 'any' 
      END START_TIME,
      CASE WHEN BI.AGGREGATE_BY = 'NONE' OR INSTR(BI.AGGREGATE_BY, 'HOST')       != 0 THEN SP.HOST             ELSE MAP(BI.HOST,       '%', 'any', BI.HOST)       END HOST,
      CASE WHEN BI.AGGREGATE_BY = 'NONE' OR INSTR(BI.AGGREGATE_BY, 'PORT')       != 0 THEN TO_VARCHAR(SP.PORT) ELSE MAP(BI.PORT,       '%', 'any', BI.PORT)       END PORT,
      CASE WHEN BI.AGGREGATE_BY = 'NONE' OR INSTR(BI.AGGREGATE_BY, 'INITIATION') != 0 THEN SP.INITIATION       ELSE MAP(BI.INITIATION, '%', 'any', BI.INITIATION) END INITIATION,
      CASE WHEN BI.AGGREGATE_BY = 'NONE' OR INSTR(BI.AGGREGATE_BY, 'PURPOSE')    != 0 THEN SP.PURPOSE          ELSE MAP(BI.PURPOSE,    '%', 'any', BI.PURPOSE)    END PURPOSE,
      TO_VARCHAR(MIN(SP.BLOCKING_PHASE_START_TIME), 'YYYY/MM/DD HH24:MI:SS') BLK_PHASE_START_TIME,
      TO_VARCHAR(MIN(SP.CRITICAL_PHASE_START_TIME), 'YYYY/MM/DD HH24:MI:SS') CRIT_PHASE_START_TIME,
      TO_VARCHAR(MIN(SP.END_TIME), 'YYYY/MM/DD HH24:MI:SS') END_TIME,
      COUNT(*) NUM_SAVEPOINTS,
      AVG(SP.DURATION) / 1000000 AVG_DURATION_S,
      SUM(SP.DURATION) / 1000000 SUM_DURATION_S,
      AVG(SP.BLOCKING_PHASE_DURATION) / 1000000 AVG_BLOCKING_PHASE_S,
      AVG(SP.WAIT_FOR_LOCK_DURATION) / 1000000 AVG_WAIT_FOR_LOCK_PHASE_S,
      AVG(SP.CRITICAL_PHASE_DURATION) / 1000000 AVG_CRITICAL_PHASE_S,
      AVG(SP.TOTAL_SIZE) / 1024 / 1024 AVG_SIZE_MB,
      SUM(SP.TOTAL_SIZE) / 1024 / 1024 SUM_SIZE_MB,
      AVG(MAP(SP.TOTAL_SIZE, 0, 0, SP.FLUSHED_ROWSTORE_SIZE / SP.TOTAL_SIZE * 100)) RS_SIZE_PCT,
      AVG(SP.RETRY_COUNT) AVG_RETRIES
    FROM
    ( SELECT
        HOST,
        PORT,
        TIMEZONE,
        BEGIN_TIME,
        END_TIME,
        MIN_BLOCKING_PHASE_DURATION_S,
        MIN_WAIT_FOR_LOCK_PHASE_DURATION_S,
        MIN_CRITICAL_PHASE_DURATION_S,
        MIN_SAVEPOINT_DURATION_S,
        MIN_WRITE_SIZE_GB,
        INITIATION,
        PURPOSE,
        DATA_SOURCE,
        AGGREGATE_BY,
        MAP(TIME_AGGREGATE_BY,
          'NONE',        'YYYY/MM/DD HH24:MI:SS:FF7',
          'HOUR',        'YYYY/MM/DD HH24',
          'DAY',         'YYYY/MM/DD (DY)',
          'HOUR_OF_DAY', 'HH24',
          TIME_AGGREGATE_BY ) TIME_AGGREGATE_BY
      FROM
      ( SELECT                                                         /* Modification section */
          TO_TIMESTAMP('2019/06/14 00:00:00', 'YYYY/MM/DD HH24:MI:SS') BEGIN_TIME,
          TO_TIMESTAMP('2019/06/14 17:00:00', 'YYYY/MM/DD HH24:MI:SS') END_TIME,
          'SERVER' TIMEZONE,                              /* SERVER, UTC */
          '%' HOST,
          '%' PORT,
          -1 MIN_BLOCKING_PHASE_DURATION_S,
          -1 MIN_WAIT_FOR_LOCK_PHASE_DURATION_S,
          -1 MIN_CRITICAL_PHASE_DURATION_S,
          -1 MIN_SAVEPOINT_DURATION_S,
          -1 MIN_WRITE_SIZE_GB,
          '%' INITIATION,
          '%' PURPOSE,
          'CURRENT' DATA_SOURCE,                        /* CURRENT, HISTORY */
          'NONE' AGGREGATE_BY,         /* HOST, PORT, TIME, INITIATION, PURPOSE or comma separated combinations, NONE for no aggregation */
          'TS900' TIME_AGGREGATE_BY     /* HOUR, DAY, HOUR_OF_DAY or database time pattern, TS<seconds> for time slice, NONE for no aggregation */
        FROM
          DUMMY
      )
    ) BI,
    ( SELECT
        'CURRENT' DATA_SOURCE,
        HOST,
        PORT,
        START_TIME,
        ADD_SECONDS(CRITICAL_PHASE_START_TIME, - CRITICAL_PHASE_WAIT_TIME / 1000000) BLOCKING_PHASE_START_TIME,
        CRITICAL_PHASE_START_TIME,
        ADD_SECONDS(START_TIME, DURATION / 1000000) END_TIME,
        DURATION,
        CRITICAL_PHASE_WAIT_TIME WAIT_FOR_LOCK_DURATION,
        CRITICAL_PHASE_DURATION,
        CRITICAL_PHASE_WAIT_TIME + CRITICAL_PHASE_DURATION BLOCKING_PHASE_DURATION,
        TOTAL_SIZE,
        FLUSHED_ROWSTORE_SIZE,
        INITIATION,
        PURPOSE,
        PREPARE_FLUSH_RETRY_COUNT RETRY_COUNT
      FROM
        M_SAVEPOINTS
      UNION ALL
      SELECT DISTINCT
        'HISTORY' DATA_SOURCE,
        HOST,
        PORT,
        START_TIME,
        ADD_SECONDS(CRITICAL_PHASE_START_TIME, - CRITICAL_PHASE_WAIT_TIME / 1000000) BLOCKING_PHASE_START_TIME,
        CRITICAL_PHASE_START_TIME,
        ADD_SECONDS(START_TIME, DURATION / 1000000) END_TIME,
        DURATION,
        CRITICAL_PHASE_WAIT_TIME WAIT_FOR_LOCK_DURATION,
        CRITICAL_PHASE_DURATION,
        CRITICAL_PHASE_WAIT_TIME + CRITICAL_PHASE_DURATION BLOCKING_PHASE_DURATION,
        TOTAL_SIZE,
        FLUSHED_ROWSTORE_SIZE,
        INITIATION,
        PURPOSE,
        PREPARE_FLUSH_RETRY_COUNT RETRY_COUNT
      FROM
        _SYS_STATISTICS.HOST_SAVEPOINTS
    ) SP
    WHERE 
      SP.HOST LIKE BI.HOST AND  
      TO_VARCHAR(SP.PORT) LIKE BI.PORT AND
      CASE BI.TIMEZONE WHEN 'UTC' THEN ADD_SECONDS(SP.START_TIME, SECONDS_BETWEEN(CURRENT_TIMESTAMP, CURRENT_UTCTIMESTAMP)) ELSE SP.START_TIME END BETWEEN BI.BEGIN_TIME AND BI.END_TIME AND
      SP.INITIATION LIKE BI.INITIATION AND
      SP.PURPOSE LIKE BI.PURPOSE AND
      ( BI.MIN_BLOCKING_PHASE_DURATION_S = -1 OR 
          SP.BLOCKING_PHASE_DURATION / 1000000 >= BI.MIN_BLOCKING_PHASE_DURATION_S) AND
      ( BI.MIN_WAIT_FOR_LOCK_PHASE_DURATION_S = -1 OR
          SP.WAIT_FOR_LOCK_DURATION / 1000000 >= BI.MIN_WAIT_FOR_LOCK_PHASE_DURATION_S ) AND
      ( BI.MIN_CRITICAL_PHASE_DURATION_S = -1 OR
          SP.CRITICAL_PHASE_DURATION / 1000000 >= BI.MIN_CRITICAL_PHASE_DURATION_S ) AND
      ( BI.MIN_SAVEPOINT_DURATION_S = -1 OR 
        SP.DURATION / 1000000 >= BI.MIN_SAVEPOINT_DURATION_S ) AND
      ( BI.MIN_WRITE_SIZE_GB = -1 OR
        SP.TOTAL_SIZE / 1024 / 1024 / 1024 >= BI.MIN_WRITE_SIZE_GB ) AND
      SP.DATA_SOURCE LIKE BI.DATA_SOURCE
    GROUP BY
      CASE 
        WHEN BI.AGGREGATE_BY = 'NONE' OR INSTR(BI.AGGREGATE_BY, 'TIME') != 0 THEN 
          CASE 
            WHEN BI.TIME_AGGREGATE_BY LIKE 'TS%' THEN
              TO_VARCHAR(ADD_SECONDS(TO_TIMESTAMP('2014/01/01 00:00:00', 'YYYY/MM/DD HH24:MI:SS'), FLOOR(SECONDS_BETWEEN(TO_TIMESTAMP('2014/01/01 00:00:00', 
              'YYYY/MM/DD HH24:MI:SS'), CASE BI.TIMEZONE WHEN 'UTC' THEN ADD_SECONDS(SP.START_TIME, SECONDS_BETWEEN(CURRENT_TIMESTAMP, CURRENT_UTCTIMESTAMP)) ELSE SP.START_TIME END) / SUBSTR(BI.TIME_AGGREGATE_BY, 3)) * SUBSTR(BI.TIME_AGGREGATE_BY, 3)), 'YYYY/MM/DD HH24:MI:SS')
            ELSE TO_VARCHAR(CASE BI.TIMEZONE WHEN 'UTC' THEN ADD_SECONDS(SP.START_TIME, SECONDS_BETWEEN(CURRENT_TIMESTAMP, CURRENT_UTCTIMESTAMP)) ELSE SP.START_TIME END, BI.TIME_AGGREGATE_BY)
          END
        ELSE 'any' 
      END,
      CASE WHEN BI.AGGREGATE_BY = 'NONE' OR INSTR(BI.AGGREGATE_BY, 'HOST')       != 0 THEN SP.HOST             ELSE MAP(BI.HOST,       '%', 'any', BI.HOST)       END,
      CASE WHEN BI.AGGREGATE_BY = 'NONE' OR INSTR(BI.AGGREGATE_BY, 'PORT')       != 0 THEN TO_VARCHAR(SP.PORT) ELSE MAP(BI.PORT,       '%', 'any', BI.PORT)       END,
      CASE WHEN BI.AGGREGATE_BY = 'NONE' OR INSTR(BI.AGGREGATE_BY, 'INITIATION') != 0 THEN SP.INITIATION       ELSE MAP(BI.INITIATION, '%', 'any', BI.INITIATION) END,
      CASE WHEN BI.AGGREGATE_BY = 'NONE' OR INSTR(BI.AGGREGATE_BY, 'PURPOSE')    != 0 THEN SP.PURPOSE          ELSE MAP(BI.PURPOSE,    '%', 'any', BI.PURPOSE)    END
  )
)
ORDER BY
  START_TIME DESC,
  HOST,
  PORT

Нужна помощь, чтобы понять последовательность выполнения блоков кода.

...