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.