5.18. Estadísticas y selectividad para tipos temporales

5.18.1. Colecta de estadísticas

El planificador de PostgreSQL se basa en información estadística sobre el contenido de las tablas para generar el plan de ejecución más eficiente para las consultas. Estas estadísticas incluyen una lista de algunos de los valores más comunes en cada columna y un histograma que muestra la distribución aproximada de datos en cada columna. Para tablas grandes, se toma una muestra aleatoria del contenido de la tabla, en lugar de examinar cada fila. Esto permite analizar tablas grandes en poco tiempo. La información estadística es recopilada por el comando ANALYZE y es almacenada en la tabla de catálogo pg_statistic. Dado que diferentes tipos de estadísticas pueden ser apropiados para diferentes tipos de datos, la tabla sólo almacena estadísticas muy generales (como el número de valores nulos) en columnas dedicadas. Todo lo demás se almacena en cinco “slots”, que son pares de columnas de matriz que almacenan las estadísticas de una columna de un tipo arbitrario.

Las estadísticas recopiladas para tipos de tiempo y tipos temporales se basan en las recopiladas por PostgreSQL para tipos escalares y tipos de rango. Para tipos escalares, como float, se recopilan las siguientes estadísticas:

  1. fracción de valores nulos,

  2. ancho promedio, en bytes, de valores no nulos,

  3. número de diferentes valores no nulos,

  4. matriz de los valores más comunes y matriz de sus frecuencias,

  5. histograma de valores, donde se excluyen los valores más comunes,

  6. correlación entre el orden de filas físico y lógico.

Para los tipos de rango, como tstzrange, se recopilan tres histogramas adicionales:

  1. histograma de longitud de rangos no vacíos,

  2. histogramas de límites superior e inferior.

Para geometrías, además de (1)–(3), se recopilan las siguientes estadísticas:

  1. número de dimensiones de los valores, cuadro delimitador N-dimensional, número de filas en la tabla, número de filas en la muestra, número de valores no nulos,

  2. Histograma N-dimensional que divide el cuadro delimitador en varias celdas y mantiene la proporción de valores que se cruzan con cada celda.

Las estadísticas recopiladas para columnas de los nuevos tipos de tiempo timestampset, period y periodset replican las recopiladas por PostgreSQL para tstzrange. Esto es claro para el tipo period, que es equivalente a tszrange, excepto que los períodos no pueden estar vacíos. Para los tipos timestampset y periodset, un valor se convierte en su cuadro delimitador que es un period y luego se recopilan las estadísticas del tipo period.

Las estadísticas recopiladas para columnas de los tipos temporales dependen del subtipo temporal y del tipo base. Además de las estadísticas (1)–(3) que se recopilan para todos los tipos temporales, las estadísticas se recopilan para la dimensiónes de tiempo y de valor de forma independiente. Más precisamente, se recopilan las siguientes estadísticas para la dimensión de tiempo:

  • Para columnas de subtipo instante, las estadísticas (4)–(6) se recopilan para las marcas de tiempo.

  • Para columnas de otro subtipo, las estadísticas (7)–(8) se recopilan para los períodos delimitadores.

Las siguientes estadísticas se recopilan para la dimensión de valores:

  • Para columnas de tipos temporales con interpolación escalonada (es decir, tbool, ttext o tint):

    • Para el subtipo instante, las estadísticas (4)–(6) se recopilan para los valores.

    • Para todas los demás subtipos, las estadísticas (7)–(8) se recopilan para los valores.

  • Para columnas de tipos temporales flotantes (es decir, tfloat):

    • Para el subtipo instante, las estadísticas (4)–(6) se recopilan para los valores.

    • Para todas los demás subtipos, las estadísticas (7)–(8) se recopilan por los rangos delimitadores de valores.

  • Para columnas de tipos de puntos temporales (es decir, tgeompoint y tgeogpoint) las estadísticas (9)–(10) se compilan para los puntos.

5.18.2. Estimación de la selectividad de los operadores

Los operadores booleanos en PostgreSQL se pueden asociar con dos funciones de selectividad, que calculan la probabilidad de que un valor de un tipo dado coincida con un criterio dado. Estas funciones de selectividad se basan en las estadísticas recopiladas. Hay dos tipos de funciones de selectividad. Las funciones de selectividad de restricción intentan estimar el porcentaje de filas en una tabla que satisfacen una condición en la cláusula WHERE de la forma column OP constant. Por otro lado, las funciones de selectividad de unión intentan estimar el porcentaje de filas en una tabla que satisfacen una condición en la cláusula WHERE de la forma table1.column1 OP table2.column2.

MobilityDB define 23 clases de operadores booleanos (como=, <, &&, <<, etc.), cada uno de los cuales puede tener como argumentos izquierdo o derecho un tipo PostgreSQL (como integer, timestamptz, etc.) o un nuevo tipo MobilityDB (como period, tint_seq, etc.). Como consecuencia, existe un número muy elevado de operadores con diferentes argumentos a considerar para las funciones de selectividad. El enfoque adoptado fue agrupar estas combinaciones en clases correspondientes a las dimensiones de valor o de tiempo. Las clases corresponden al tipo de estadísticas recopiladas como se explica en la sección anterior.

Actualmente, sólo están implementadas las funciones de selectividad de restricción para tipos temporales, mientras que las funciones de selectividad de unión dan un valor de selectividad predeterminado según el operador. Está previsto implementar las funciones de selectividad de unión en el futuro.