Descripción
Contiene estadísticas de selectividad obtenidas por muestreo durante la lectura de tablas MergeTree. La tabla se rellena solo cuando predicate_statistics_sample_rate es mayor que 0.
Use esta tabla para examinar hasta qué punto son selectivos los predicados de usuario en cargas de trabajo reales y cuántos gránulos quedan después del filtrado por clave primaria o por índice de omisión. Los datos sirven de entrada para recomendaciones de índices y proyecciones basadas en la carga de trabajo.
Estructura de las filas
Una sola consulta puede producir dos tipos de filas en system.predicate_statistics_log:
- Filas de filtro, emitidas en cada paso de prewhere/filtro en
MergeTreeSelectProcessor. Completanpredicate_expression,input_rows,passed_rows,filter_selectivityy las columnas del predicado completototal_input_rows,total_passed_rows,total_selectivity. Las columnas relacionadas con índices quedan vacías. - Filas de índice, emitidas en cada paso de lectura en
ReadFromMergeTree. Completan los arraysindex_names,index_types,total_granules,granules_aftereindex_selectivities, con una entrada por cada etapa del índice (clave primaria, partición, índices de omisión). Las columnas relacionadas con predicados quedan vacías.
Las filas de filtro y las filas de índice de la misma consulta comparten el mismo query_id y la misma table, por lo que se pueden unir cuando se necesiten ambas.
Muestreo y sobrecarga
El muestreo se controla con predicate_statistics_sample_rate:
0desactiva la recopilación.1toma una muestra de cada consulta.N > 1toma muestras de aproximadamente1 / Nde las consultas, aplicando hash aquery_id.
Los valores más bajos generan más datos, pero añaden carga de CPU en la ruta de lectura y más escrituras en el log del sistema. Después de habilitar este ajuste, usa SYSTEM FLUSH LOGS si necesitas que las filas aparezcan de inmediato.
Columnas
hostname(LowCardinality(String)) — Hostname del servidor que ejecuta la consulta.event_date(Date) — Fecha del evento.event_time(DateTime) — Marca temporal en la que se escribió esta entrada de log.database(LowCardinality(String)) — Nombre de la base de datos de la tabla de destino.table(LowCardinality(String)) — Nombre de la tabla de destino.query_id(String) — ID de la consulta para vincularla de nuevo con query_log.predicate_expression(String) — Expresión de filtro completa procesada en este paso de prewhere/filter (volcado de ActionsDAG).input_rows(UInt64) — Filas que entran en este paso de prewhere/filter.passed_rows(UInt64) — Filas que pasan este paso de prewhere/filter.filter_selectivity(Float64) — Selectividad de este paso: passed_rows / input_rows.total_input_rows(UInt64) — Filas que entran en el primer paso de prewhere (total de filas leídas de los gránulos).total_passed_rows(UInt64) — Filas que pasan todos los pasos de prewhere (filas entregadas a la consulta).total_selectivity(Float64) — Selectividad del predicado completo: total_passed_rows / total_input_rows.index_names(Array(LowCardinality(String))) — Nombres de los índices aplicados, por ejemplo ['PrimaryKey', 'idx_bf_status'] (solo para filas de índice).index_types(Array(LowCardinality(String))) — Tipos de índices aplicados: PrimaryKey, Skip, MinMax, Partition (solo para filas de índice).total_granules(Array(UInt64)) — Gránulos que entran en cada etapa del índice (solo para filas de índice).granules_after(Array(UInt64)) — Gránulos restantes después de cada etapa del índice (solo para filas de índice).index_selectivities(Array(Float64)) — Selectividad por índice: granules_after / total_granules (solo para filas de índice).
Ejemplo
SET predicate_statistics_sample_rate = 1;
SELECT *
FROM hits
WHERE URL LIKE '%/product/%' AND EventDate >= today() - 7
FORMAT Null;
SYSTEM FLUSH LOGS predicate_statistics_log;
SELECT
query_id,
predicate_expression,
round(filter_selectivity, 3) AS step_selectivity,
round(total_selectivity, 3) AS query_selectivity,
index_names,
index_selectivities
FROM system.predicate_statistics_log
WHERE table = 'hits'
ORDER BY event_time DESC
LIMIT 10;