¿Cuándo recopilaste estadísticas por última vez (en Teradata) (2)?

En capítulos anteriores vimos cómo interpretar los datos de fecha y hora de la última recopilación de estadísticas para una tabla basándonos en la columna ‘fieldstatistics’ de la tabla dbc.tvfields. El caso es que en dicha tabla dbc.tvfields se almacenan los datos de las estadísticas recopìladas PARA COLUMNAS DE UNA EN UNA.

Pero Teradata permite calcular estadísticas para grupos de columnas (sean éstas índices o no). Esto lo podemos ver si ejecutamos un HELP STATISTICS:

 BTEQ -- Enter your SQL request or BTEQ command:
HELP STATISTICS MY_DB.PRUEBA02;

 *** Help information returned. 2 rows.
 *** Total elapsed time was 1 second.

Date     Time     Unique Values        Column Names
-------- -------- -------------------- ------------------------
11/12/21 18:40:17                    3 ID_N2
11/12/21 19:38:02                    4 ID_N2,C_TXT2,D_DATE2

Y aquí viene lo bueno, porque las estadísticas multi-columnas no se guardan en nuestra conocida dbc.tvfields, sino en dbc.Indexes, donde también existe la famosa columna VARBYTE(16383), sólo que en este caso se llama IndexStatistics. Hay que decir que las vistas DBC.IndexStats y DBC.MultiColumnStats toman sus datos de ella. Y también es importante saber que los datos de las estadísticas se guardan únicamente en la columna IndexStatistics DE LA PRIMERA COLUMNA del grupo:

SELECT DatabaseName,
       TableName,
       StatisticsId,
       ColumnName,
       ColumnPosition,
       ColumnsStatistics
  FROM DBC.MultiColumnStats
 WHERE databasename = 'MY_DB'
   AND TableName='PRUEBA02'
 ORDER BY ColumnPosition;

 *** Query completed. 3 rows found. 5 columns returned.
 *** Total elapsed time was 1 second.

DatabaseName TableName StatisticsId ColumnName ColumnPosition  ColumnsStatistics
------------ --------- ------------ ---------- --------------  ----------------------
MY_DB        PRUEBA02           129 ID_N2                   1  DB070C15132602310300...
MY_DB        PRUEBA02           129 C_TXT2                  2  (null)
MY_DB        PRUEBA02           129 D_DATE2                 3  (null)

Muy importante es StatisticsId, ya que indica que las columnas pertenecen a un mismo grupo sobre el que se han recopilado las estadísticas (129). Si recopilamos para otro grupo:

 BTEQ -- Enter your SQL request or BTEQ command:
COLLECT STATISTICS ON MY_DB.PRUEBA02 COLUMN(C_TXT2,D_DATE2);

 *** Update completed. One row changed.
 *** Total elapsed time was 1 second.

 BTEQ -- Enter your SQL request or BTEQ command:
SELECT DatabaseName,
       TableName,
       StatisticsId,
       ColumnName,
       ColumnPosition,
       ColumnsStatistics
  FROM DBC.MultiColumnStats
 WHERE databasename = 'MY_DB'
   AND TableName='PRUEBA02'
 ORDER BY StatisticsId, ColumnPosition;

 *** Query completed. 5 rows found. 6 columns returned.
 *** Total elapsed time was 1 second.

DatabaseName TableName StatisticsId ColumnName ColumnPosition  ColumnsStatistics
------------ --------- ------------ ---------- --------------  --------------------
MY_DB        PRUEBA02           129 ID_N2                   1  DB070C15132602310300...
MY_DB        PRUEBA02           129 C_TXT2                  2  (null)
MY_DB        PRUEBA02           129 D_DATE2                 3  (null)
MY_DB        PRUEBA02           130 C_TXT2                  1  DB070C15142314510300...
MY_DB        PRUEBA02           130 D_DATE2                 2  (null)

vemos que StatisticsId identifica las columnas que lo componen.

Pues con todo esto podemos hacer:

--
-- LAST_MULTISTATS. View that shows the DatabaseName, TableName, ColumnName, ColumnGroup, Date & Time
--                  of the last COLLECT STATS executed over a group of columns.
--
-- Author: Carlos Álvarez.
--
REPLACE VIEW MY_DB.LAST_MULTISTATS
AS
SELECT DatabaseName,
       TableName   ,
       ColumnName  ,
       ColumnGroup ,
       CAST(TRIM("AÑO") || '-' ||
            TRIM("MES") || '-' ||
            TRIM("DÍA") AS DATE) Fecha,
       CAST(TRIM("HORA")   || ':' ||
            TRIM("MINUTO") || ':' ||
            TRIM("SEGUNDO") AS TIME(0)) Hora
 FROM (
        SELECT
           c.databasenamei (VARCHAR(30)) "DatabaseName",
           b.tvmnamei      (VARCHAR(30)) "TableName",
           d.fieldname     (VARCHAR(30)) "ColumnName",
           a.IndexNumber                 "ColumnGroup",
           HASHBUCKET( CAST(SUBSTR(a.IndexStatistics,2,1) ||
                            SUBSTR(a.IndexStatistics,1,1) ||
                            '0000'XB AS BYTE(4)) ) (FORMAT '9999') "AÑO",
           HASHBUCKET( CAST('00'XB ||
                            SUBSTR(a.IndexStatistics,3,1) ||
                            '0000'XB AS BYTE(4)) ) (FORMAT '99') "MES",
           HASHBUCKET( CAST('00'XB ||
                            SUBSTR(a.IndexStatistics,4,1) ||
                            '0000'XB AS BYTE(4)) ) (FORMAT '99') "DÍA",
           HASHBUCKET( CAST('00'XB ||
                            SUBSTR(a.IndexStatistics,5,1) ||
                            '0000'XB AS BYTE(4)) ) (FORMAT '99') "HORA",
           HASHBUCKET( CAST('00'XB ||
                            SUBSTR(a.IndexStatistics,6,1) ||
                            '0000'XB AS BYTE(4)) ) (FORMAT '99') "MINUTO",
           HASHBUCKET( CAST('00'XB ||
                            SUBSTR(a.IndexStatistics,7,1) ||
                            '0000'XB AS BYTE(4)) ) (FORMAT '99') "SEGUNDO"
      FROM
          dbc.Indexes a,
          dbc.Indexes aa,
          dbc.tvm b,
          dbc.dbase c,
          dbc.tvfields d
    WHERE a.tableid = aa.tableid
      AND a.IndexNumber = aa.IndexNumber
      AND a.tableid = b.tvmid
      AND b.tablekind = 'T'
      AND b.databaseid = c.databaseid
      AND a.IndexStatistics IS NOT NULL
      AND b.TVMid = d.tableid
      AND aa.fieldid = d.fieldid
      ) PRE
;

Y entonces:

 BTEQ -- Enter your SQL request or BTEQ command:
SELECT *
  FROM MY_DB.LAST_MULTISTATS
 WHERE TABLENAME='PRUEBA02';

 *** Query completed. 5 rows found. 6 columns returned.
 *** Total elapsed time was 1 second.

DatabaseName TableName ColumnName ColumnGroup       Fecha      Hora
------------ --------- ---------- -----------  ----------  --------
MY_DB        PRUEBA02  C_TXT2             129  2011-12-21  19:38:02
MY_DB        PRUEBA02  D_DATE2            129  2011-12-21  19:38:02
MY_DB        PRUEBA02  ID_N2              129  2011-12-21  19:38:02
MY_DB        PRUEBA02  C_TXT2             130  2011-12-21  20:35:20
MY_DB        PRUEBA02  D_DATE2            130  2011-12-21  20:35:20

y combinarlo con la vista que creamos aquí (con un simple ‘UNION ALL’, por ejemplo) es un juego de niños.

Saludos.

Carlos.

Anuncios

One Response to ¿Cuándo recopilaste estadísticas por última vez (en Teradata) (2)?

  1. […] en el que me decía que las “queries” que puse en los artículos “¿Cuándo recopilaste estadísticas por última vez (en Teradata)?” le estaban fallando. Me indicaba que los estaba ejecutando en un Teradata […]

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: