mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-22 05:31:41 +08:00
https://github.com/timescale/timescaledb/actions/runs/11825528841/job/32949516502?pr=7434
144 lines
4.7 KiB
SQL
144 lines
4.7 KiB
SQL
-- This file and its contents are licensed under the Timescale License.
|
|
-- Please see the included NOTICE for copyright information and
|
|
-- LICENSE-TIMESCALE for a copy of the license.
|
|
|
|
\ir include/setup_hypercore.sql
|
|
|
|
-- To generate plans consistently.
|
|
set max_parallel_workers_per_gather to 0;
|
|
|
|
-- Start without these indexes
|
|
drop index hypertable_location_id_idx;
|
|
drop index hypertable_device_id_idx;
|
|
|
|
--
|
|
-- Test ANALYZE.
|
|
--
|
|
-- First create a separate regular table with the chunk data as a
|
|
-- reference of accurate stats. Analyze it and compare with analyze
|
|
-- on the original chunk.
|
|
--
|
|
create table normaltable (like :chunk1);
|
|
insert into normaltable select * from :chunk1;
|
|
|
|
create view relstats as
|
|
select oid::regclass as relid, reltuples
|
|
from pg_class
|
|
order by relid;
|
|
|
|
create view relstats_compare as
|
|
select * from relstats where relid in ('normaltable'::regclass, :'chunk1'::regclass);
|
|
|
|
create view attrstats as
|
|
select format('%I.%I', schemaname, tablename)::regclass as relid,
|
|
attname,
|
|
n_distinct,
|
|
array_to_string(most_common_vals, e',') as most_common_vals
|
|
from pg_stats
|
|
order by relid, attname;
|
|
|
|
create view attrstats_compare as
|
|
select * from attrstats where relid in ('normaltable'::regclass, :'chunk1'::regclass);
|
|
|
|
create view attrstats_diff as
|
|
select attname, n_distinct, most_common_vals from attrstats where relid = 'normaltable'::regclass
|
|
except
|
|
select attname, n_distinct, most_common_vals from attrstats where relid = :'chunk1'::regclass;
|
|
|
|
create view attrstats_same as
|
|
select count(*)=0 as stats_are_the_same from attrstats_diff;
|
|
|
|
-- No stats yet
|
|
select * from relstats_compare;
|
|
select * from attrstats_compare;
|
|
|
|
-- Check that the estimated rows is the same for the chunk and the
|
|
-- normal table and in the right ballpark
|
|
explain (analyze, costs off, timing off, summary off)
|
|
select * from :chunk1 where location_id = 1;
|
|
explain (analyze, costs off, timing off, summary off)
|
|
select * from normaltable where location_id = 1;
|
|
|
|
-- Changing to hypercore will update relstats since it process all
|
|
-- the data
|
|
alter table :chunk1 set access method hypercore;
|
|
-- Creating an index on normaltable will also update relstats
|
|
create index normaltable_location_id_idx on normaltable (location_id);
|
|
|
|
-- Relstats should be the same for both tables, except for pages since
|
|
-- a hypercore is compressed. Column stats is not updated.
|
|
analyze :chunk1;
|
|
analyze normaltable;
|
|
select * from relstats_compare;
|
|
select * from attrstats_compare;
|
|
|
|
-- Drop the index again, we'll need to recreate it again later
|
|
drop index normaltable_location_id_idx;
|
|
|
|
-- Check that the estimated rows is the same for the chunk and the
|
|
-- normal table and in the right ballpark
|
|
select count(*) from :chunk1 where location_id = 1;
|
|
explain (analyze, costs off, timing off, summary off)
|
|
select * from :chunk1 where location_id = 1;
|
|
explain (analyze, costs off, timing off, summary off)
|
|
select * from normaltable where location_id = 1;
|
|
|
|
-- ANALYZE directly on chunk
|
|
analyze :chunk1;
|
|
analyze normaltable;
|
|
|
|
-- Stats after analyze
|
|
select * from relstats_compare;
|
|
select * from attrstats_same;
|
|
|
|
-- Check that the estimated rows is now correct based on stats (reltuples)
|
|
explain (analyze, costs off, timing off, summary off)
|
|
select * from :chunk1 where location_id = 1;
|
|
explain (analyze, costs off, timing off, summary off)
|
|
select * from normaltable where location_id = 1;
|
|
|
|
delete from :chunk1 where location_id=1;
|
|
delete from normaltable where location_id=1;
|
|
|
|
analyze :chunk1;
|
|
analyze normaltable;
|
|
select * from relstats_compare;
|
|
select * from attrstats_same;
|
|
|
|
-- Creating an index should update relstats but not attrstats. Note
|
|
-- also that this will be a segmentby index, and because it only
|
|
-- indexes compressed tuples, it is extra important to check reltuples
|
|
-- is correct.
|
|
create index hypertable_location_id_idx on :hypertable (location_id);
|
|
create index normaltable_location_id_idx on normaltable (location_id);
|
|
|
|
-- Test how VACUUM affects stats (or not)
|
|
select * from relstats_compare;
|
|
|
|
vacuum :chunk1;
|
|
vacuum normaltable;
|
|
|
|
select * from relstats_compare;
|
|
select * from attrstats_same;
|
|
|
|
vacuum analyze :chunk1;
|
|
vacuum analyze normaltable;
|
|
|
|
select * from relstats_compare;
|
|
select * from attrstats_same;
|
|
|
|
-- ANALYZE also via hypertable root and show that it will recurse to
|
|
-- chunks. Make sure the chunk also has partially compressed data
|
|
alter table :chunk2 set access method hypercore;
|
|
update :hypertable set device_id = 2 where device_id = 1;
|
|
select * from relstats where relid = :'chunk2'::regclass;
|
|
vacuum analyze :chunk2;
|
|
select * from attrstats where relid = :'chunk2'::regclass;
|
|
select count(*) from :chunk2;
|
|
|
|
analyze :hypertable;
|
|
|
|
select * from relstats where relid = :'chunk2'::regclass;
|
|
-- Just show that there are attrstats via a count avoid flaky output
|
|
select count(*) from attrstats where relid = :'chunk2'::regclass;
|