| From: | ZizhuanLiu X-MAN <44973863(at)qq(dot)com> |
|---|---|
| To: | pgsql-hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Cc: | Ilia Evdokimov <ilya(dot)evdokimov(at)tantorlabs(dot)com>, tgl <tgl(at)sss(dot)pgh(dot)pa(dot)us>, tomas <tomas(at)vondra(dot)me>, dean(dot)a(dot)rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)com>, guofenglinux <guofenglinux(at)gmail(dot)com> |
| Subject: | Re: Optimize MCV stats for sortable types and utilize sorted-order properties |
| Date: | 2026-10-15 01:41:45 |
| Message-ID: | tencent_85DF2D9676D4388D88F0AB6D7CB4D513CF08@qq.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Subject: ANALYZE correctness and performance testing
Hi hackers,
The patch is now reaching a relatively complete stage, and all CFBot tests are passing.
I am now starting to evaluate its correctness and performance more systematically.
As the first step, I focused on the ANALYZE side, particularly on the correctness of
generating value-sorted MCV statistics and the performance overhead of collecting them.
For the test, I created a table with 100,020 rows and set the statistics target to 10,000.
Most values occur 10 times, while three values have slightly higher frequencies.
The resulting MCV statistics show the expected difference between v14 and the current master.
With v14, where STATISTIC_KIND_MCV_VALUE_SORTED is used, the MCV values are sorted by value:
mcv_type | no | value | frequency
-----------------------------------+----+------------------+-------------
8-STATISTIC_KIND_MCV_VALUE_SORTED | 1 | "PostgreSQL 001" | 0.10002
8-STATISTIC_KIND_MCV_VALUE_SORTED | 2 | "PostgreSQL 002" | 0.099980004
8-STATISTIC_KIND_MCV_VALUE_SORTED | 3 | "PostgreSQL 003" | 0.099980004
8-STATISTIC_KIND_MCV_VALUE_SORTED | 4 | "PostgreSQL 004" | 0.099980004
8-STATISTIC_KIND_MCV_VALUE_SORTED | 5 | "PostgreSQL 005" | 0.10003999
8-STATISTIC_KIND_MCV_VALUE_SORTED | 6 | "PostgreSQL 006" | 0.099980004
8-STATISTIC_KIND_MCV_VALUE_SORTED | 7 | "PostgreSQL 007" | 0.099980004
8-STATISTIC_KIND_MCV_VALUE_SORTED | 8 | "PostgreSQL 008" | 0.099980004
8-STATISTIC_KIND_MCV_VALUE_SORTED | 9 | "PostgreSQL 009" | 0.099980004
8-STATISTIC_KIND_MCV_VALUE_SORTED | 10 | "PostgreSQL 010" | 0.10007998
(10 rows)
In contrast, on master, the MCVs are sorted by frequency:
mcv_type | no | value | frequency
----------------------+----+------------------+-------------
1-STATISTIC_KIND_MCV | 1 | "PostgreSQL 010" | 0.10007998
1-STATISTIC_KIND_MCV | 2 | "PostgreSQL 005" | 0.10003999
1-STATISTIC_KIND_MCV | 3 | "PostgreSQL 001" | 0.10002
1-STATISTIC_KIND_MCV | 4 | "PostgreSQL 002" | 0.099980004
1-STATISTIC_KIND_MCV | 5 | "PostgreSQL 003" | 0.099980004
1-STATISTIC_KIND_MCV | 6 | "PostgreSQL 004" | 0.099980004
1-STATISTIC_KIND_MCV | 7 | "PostgreSQL 006" | 0.099980004
1-STATISTIC_KIND_MCV | 8 | "PostgreSQL 007" | 0.099980004
1-STATISTIC_KIND_MCV | 9 | "PostgreSQL 008" | 0.099980004
1-STATISTIC_KIND_MCV | 10 | "PostgreSQL 009" | 0.099980004
(10 rows)
This is also consistent with the intended design: the new statistic kind keeps the
MCV values sorted by value while preserving the corresponding frequencies.
For the ANALYZE performance, I ran 100 consecutive ANALYZE operations in each case.
The total time was:
1st 2nd 3rd 4th avg
================================================================
v14: 22510.146 23805.940 24146.746 24869.801 23833.158
master: 22407.108 23095.573 24068.918 23933.353 23376.238
This corresponds to approximately:
v14: 238.33 ms / ANALYZE
master: 233.76 ms / ANALYZE
So, for this particular test case, the additional cost is about 1.95% per ANALYZE.
I would appreciate any feedback on whether this is a reasonable way to evaluate the
ANALYZE-side overhead, and whether there are other representative workloads or
cases that would be useful to test.
In particular, comments from people familiar with analyze.c, MCV generation, or statistics
collection would be very helpful. I'm also interested in whether the current implementation
introduces any unnecessary work that could be optimized further.
As the next step, I plan to measure the performance impact on the different consumers of
these statistics, including the relevant equality/range comparison and join selectivity estimation paths.
Thanks in advance for any review and suggestions.
The test SQL and the corresponding results are as follows:
---------------------
DROP TABLE IF EXISTS t_sort_mcv_100;
CREATE TABLE t_sort_mcv_100(name text);
ALTER TABLE t_sort_mcv_100 ALTER COLUMN name SET STATISTICS 10000;
select attname,attstattarget from pg_catalog.pg_attribute where attrelid = 't_sort_mcv_100'::regclass and attnum = 1;
DO $$
DECLARE i int := 0;
BEGIN
LOOP
EXIT WHEN i >= 10000;
i := i + 1;
INSERT INTO t_sort_mcv_100 SELECT repeat( 'PostgreSQL', 1) || to_char(g, '099') FROM generate_series(1, 10) g;
END LOOP;
END $$;
INSERT INTO t_sort_mcv_100 SELECT repeat( 'PostgreSQL', 1) || ' 010' FROM generate_series(1, 10) g;
INSERT INTO t_sort_mcv_100 SELECT repeat( 'PostgreSQL', 1) || ' 005' FROM generate_series(1, 6) g;
INSERT INTO t_sort_mcv_100 SELECT repeat( 'PostgreSQL', 1) || ' 001' FROM generate_series(1, 4) g;
select count(*) from t_sort_mcv_100;
---------------------
\timing on
DO $$
DECLARE i int := 0;
BEGIN
LOOP
EXIT WHEN i >= 100;
i := i + 1;
ANALYZE t_sort_mcv_100;
END LOOP;
END $$;
---------------------
WITH s AS (SELECT stakind1,stanumbers1, stavalues1::text AS values_text
FROM pg_catalog.pg_statistic
WHERE starelid = 't_sort_mcv_100'::regclass AND staattnum = 1
),
v AS ( SELECT ordinality AS n, value
FROM s, LATERAL unnest( string_to_array(trim(both '{}' FROM values_text), ',' ) )
WITH ORDINALITY AS u(value, ordinality)
),
f AS ( SELECT ordinality AS n, frequency
FROM s, LATERAL unnest(stanumbers1)
WITH ORDINALITY AS u(frequency, ordinality)
)
SELECT CASE
when s.stakind1 = 1 then '1-STATISTIC_KIND_MCV'
when s.stakind1 = 8 then '8-STATISTIC_KIND_MCV_VALUE_SORTED'
else NULL END AS MCV_TYPE
,v.n as no, v.value, f.frequency
FROM v JOIN f USING(n) JOiN s ON 1=1
ORDER BY v.n;
regards,
--
ZizhuanLiu (X-MAN)
44973863(at)qq(dot)com
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Fujii Masao | 2026-10-15 02:00:07 | Re: REPACK: warn about skipping foreign partitions |
| Previous Message | David Rowley | 2026-10-15 01:24:57 | Re: [PATCH] Add memory/disk usage for Function Scan nodes in EXPLAIN |