Dos ejemplos de escenarios explican la solución a la estimación imprecisa de las estadísticas de la tabla base de GaussDB (DWS)

Resumen: Las soluciones de operación y mantenimiento de GaussDB (DWS) se explican a través de dos escenarios de ejemplo.

Este artículo se comparte desde Huawei Cloud Community " Operación y mantenimiento de GaussDB (DWS): escenarios comunes y soluciones para la estimación imprecisa de la información estadística de la tabla base ", autor: Ge Li Ge.

Escenario 1: cuando la tabla base filtra el tipo implícito del campo, el número estimado de filas de la tabla base es demasiado pequeño

La mayoría de estos escenarios pueden ser manejados por DWS, pero si el resultado de la conversión de tipo implícita es diferente de la expresión del valor de enumeración de campo en la información estadística, dará lugar a serias desviaciones en la estimación.

El SQL original es el siguiente

SELECT * FROM dmgrpdi.dwl_inv_res_rpt_ci_grp_f WHERE period_id=202212 AND source_flag=1;

plan de ejecución correspondiente

                                                    QUERY PLAN
-------------------------------------------------------------------------------------------------------------------
  id |                            operation                             | E-rows | E-memory | E-width |  E-costs
 ----+------------------------------------------------------------------+--------+----------+---------+-----------
 1 | -> Row Adapter                                                  | 14160 | | 717 | 680025.43
 2 | ->  Vector Streaming (type: GATHER) | 14160 | | 717 | 680025.43
 3 | ->  Vector Partition Iterator                              | 14160 | 1MB      | 717 | 678241.33
 4 | ->  Partitioned CStore Scan on dwl_inv_res_rpt_ci_grp_f | 14160 | 1MB      | 717 | 678241.33
                  Predicate Information (identified by plan id)
 -------------------------------------------------------------------------------
 3 --Vector Partition Iterator
         Iterations: 1
 4 --Partitioned CStore Scan on dwl_inv_res_rpt_ci_grp_f
         Filter: ((period_id = 202212::numeric) AND ((source_flag)::bigint = 1))
         Pushdown Predicate Filter: (period_id = 202212::numeric)
         Partitions Selected by Static Prune: 36

Encontró que hay una conversión de tipo implícita en el campo source_flag, consulte las estadísticas del campo source_flag

postgres=# SELECT most_common_vals,most_common_freqs, histogram_bounds  FROM pg_stats WHERE tablename = 'dwl_inv_res_rpt_ci_grp_f' AND attname = 'source_flag';
 most_common_vals | most_common_freqs | histogram_bounds
------------------+-----------------------------------+------------------
 {01,02,04,03}    | {.440034,.241349,.217413,.101089} | {05,06}
(1 row)

Se encuentra que el resultado de la conversión de tipo implícita (1) es diferente de la expresión del valor de enumeración de campo ('01') en las estadísticas

Solución: modifique las condiciones del filtro, prohíba la conversión de tipos y use el valor constante correcto para escribir las condiciones del filtro

source_flag=1 en la instrucción SQL anterior se cambia a source_flag='01', y la instrucción SQL modificada es la siguiente

SELECT * FROM dmgrpdi.dwl_inv_res_rpt_ci_grp_f WHERE period_id=202212 AND source_flag='01';

Consultar el plan de ejecución de la nueva sentencia

                                                      QUERY PLAN
----------------------------------------------------------------------------------------------------------------------
  id |                            operation                             |  E-rows | E-memory | E-width |  E-costs
 ----+------------------------------------------------------------------+-----------+----------+---------+-----------
 1 | -> Row Adapter                                                  | 108359075 | | 717 | 480542.98
 2 | ->  Vector Streaming (type: GATHER) | 108359075 | | 717 | 480542.98
 3 | ->  Vector Partition Iterator                              | 108359075 | 1MB      | 717 | 478758.88
 4 | ->  Partitioned CStore Scan on dwl_inv_res_rpt_ci_grp_f | 108359075 | 1MB      | 717 | 478758.88
                           Predicate Information (identified by plan id)
 -------------------------------------------------------------------------------------------------
 3 --Vector Partition Iterator
         Iterations: 1
 4 --Partitioned CStore Scan on dwl_inv_res_rpt_ci_grp_f
         Filter: ((period_id = 202212::numeric) AND (source_flag = '01'::text))
         Pushdown Predicate Filter: ((period_id = 202212::numeric) AND (source_flag = '01'::text))
         Partitions Selected by Static Prune: 36

Escenario 2: cuando la tabla base se filtra en una clave principal compuesta de varias columnas, se estima que la cantidad de filas en la tabla base es demasiado grande

Este escenario se debe a que DWS adopta una correlación débil entre varias condiciones de filtro en la tabla base. Cuando varias condiciones de filtro son claves principales, el conjunto de resultados puede estar sobreestimado.

El SQL original es el siguiente

SELECT * FROM mca.mca_period_rate_t mca_rate2
WHERE period_number = '202208' AND from_currency_code = 'RMB' AND to_currency_code = 'USD'

La información de ejecución es la siguiente

 id |                      operation                       |       A-time | A-rows | E-rows | Peak Memory | E-memory | A-width | E-width | E-costs  
----+------------------------------------------------------+--------------------+--------+--------+-------------+----------+---------+---------+----------
 1 | -> Row Adapter                                      | 444.735 | 1 | 2033 | 227KB       | | | 321 | 22601.41 
 2 | ->  Vector Streaming (type: GATHER) | 444.720 | 1 | 2033 | 873KB       | | | 321 | 22601.41 
 3 | -> CStore Scan on mca_period_rate_t mca_rate2 | [435.167, 435.167] | 1 | 2033 | [5MB, 5MB] | 1MB      | | 321 | 22427.41 
                                                              Predicate Information (identified by plan id) 
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 3 --CStore Scan on mca_period_rate_t mca_rate2
        Filter: (((period_number)::text = '202208'::text) AND ((from_currency_code)::text = 'RMB'::text) AND ((to_currency_code)::text = 'USD'::text))
 Rows Removed by Filter: 425812
        Pushdown Predicate Filter: (((period_number)::text = '202208'::text) AND ((from_currency_code)::text = 'RMB'::text) AND ((to_currency_code)::text = 'USD'::text))

Se puede encontrar que la estimación del número de filas en la tabla base mca.mca_period_rate_t es demasiado grande.

Utilice la siguiente instrucción SQL para ver la definición de la tabla mca.mca_period_rate_t

SELECT pg_get_tabledef('mca.mca_period_rate_t'::regclass);

Tabla de consulta mca.mca_period_rate_t definición

SELECT pg_get_tabledef('mca.mca_period_rate_t');
SET search_path = mca;
CREATE TABLE mca_period_rate_t (
seq numeric NOT NULL,
period_number character varying(10) NOT NULL,
from_currency_code character varying(20) NOT NULL,
to_currency_code character varying(20) NOT NULL,
begin_rate numeric(35,18),
end_rate numeric(35,18),
avg_rate numeric(35,18),
creation_date timestamp(0) without time zone NOT NULL,
created_by numeric NOT NULL,
last_update_date timestamp(0) without time zone,
last_updated_by numeric,
rmb_begin_rate numeric(35,18),
usd_begin_rate numeric(35,18),
rmb_end_rate numeric(35,18),
usd_end_rate numeric(35,18),
rmb_avg_rate numeric(35,18),
usd_avg_rate numeric(35,18),
crt_cycle_id numeric,
crt_job_instance_id numeric,
last_upd_cycle_id numeric,
upd_job_instance_id numeric,
cdc_key_id character varying(128) DEFAULT sys_guid(),
end_rate2 numeric(35,18),
avg_rate2 numeric(35,18),
last_period_end_rate numeric(35,18)
)
WITH (orientation=column, compression=low, colversion=2.0, enable_delta=false)
DISTRIBUTE BY REPLICATION
TO GROUP group_version1;
CREATE UNIQUE INDEX mca_period_rate_u1 ON mca.mca_period_rate_t USING cbtree (period_number, from_currency_code, to_currency_code) TABLESPACE pg_default;

Encontré que (period_number, from_currency_code, to_currency_code) es un índice único para la combinación.

Solución: recopilar estadísticas de varias columnas para columnas de índice compuesto

Tenga en cuenta que este esquema solo es aplicable cuando la tabla base es relativamente pequeña. Debido a que las estadísticas de varias columnas necesitan usar un muestreo porcentual para calcular las estadísticas, cuando la tabla es relativamente grande, el cálculo de las estadísticas lleva mucho tiempo.

Ejecute la siguiente declaración para recopilar (período_número, desde_código_moneda, hasta_código_moneda) información estadística de varias columnas para la declaración de consulta anterior

ANALYZE mca.mca_period_rate_t((period_number, from_currency_code, to_currency_code));

Las estimaciones de recuento de filas para las tablas base vuelven a la normalidad después de recopilar estadísticas de varias columnas

 id |                                      operation                                      |       A-time | A-rows | E-rows | Peak Memory | A-width | E-width | E-costs 
----+-------------------------------------------------------------------------------------+--------------------+--------+--------+-------------+---------+---------+---------
 1 | -> Row Adapter                                                                     | 195.504 | 1 | 1 | 227KB       | | 321 | 675.14 
 2 | ->  Vector Streaming (type: GATHER) | 195.491 | 1 | 1 | 873KB       | | 321 | 675.14 
 3 | -> CStore Index Scan using mca_period_rate_u1 on mca_period_rate_t mca_rate2 | [164.344, 164.344] | 1 | 1 | [5MB, 5MB] | | 321 | 501.14 
                                                      Predicate Information (identified by plan id) 
----------------------------------------------------------------------------------------------------------------------------------------------------------
 3 --CStore Index Scan using mca_period_rate_u1 on mca_period_rate_t mca_rate2
 Index Cond: (((period_number)::text = '202208'::text) AND ((from_currency_code)::text = 'RMB'::text) AND ((to_currency_code)::text = 'USD'::text))

 

Haga clic para seguir y conocer las nuevas tecnologías de Huawei Cloud por primera vez~

{{o.nombre}}
{{m.nombre}}

Supongo que te gusta

Origin my.oschina.net/u/4526289/blog/9800840
Recomendado
Clasificación