AdvancedTopics: partitioning.sql

File partitioning.sql, 9.2 KB (added by 231169, 4 days ago)
Line 
1-- partitioning
2
3--======
4-- product_attribute_values
5--======
6
7SET search_path TO myschema;
8
9-- 1. create master table
10CREATE TABLE PRODUCT_ATTRIBUTE_VALUES_P (
11 variant_id int8 NOT NULL,
12 attribute_id int8 NOT NULL,
13 attr_value varchar(255) NOT NULL,
14 -- pk contains attribute_id
15 PRIMARY KEY (variant_id, attribute_id)
16) PARTITION BY LIST (attribute_id);
17
18-- 2. create partitions for main attributes
19CREATE TABLE pav_processor PARTITION OF PRODUCT_ATTRIBUTE_VALUES_P FOR VALUES IN (1);
20CREATE TABLE pav_ram PARTITION OF PRODUCT_ATTRIBUTE_VALUES_P FOR VALUES IN (2);
21CREATE TABLE pav_storage PARTITION OF PRODUCT_ATTRIBUTE_VALUES_P FOR VALUES IN (3);
22CREATE TABLE pav_screen_size PARTITION OF PRODUCT_ATTRIBUTE_VALUES_P FOR VALUES IN (4);
23CREATE TABLE pav_display_type PARTITION OF PRODUCT_ATTRIBUTE_VALUES_P FOR VALUES IN (5);
24CREATE TABLE pav_battery PARTITION OF PRODUCT_ATTRIBUTE_VALUES_P FOR VALUES IN (6);
25CREATE TABLE pav_gpu PARTITION OF PRODUCT_ATTRIBUTE_VALUES_P FOR VALUES IN (7);
26CREATE TABLE pav_color PARTITION OF PRODUCT_ATTRIBUTE_VALUES_P FOR VALUES IN (8);
27CREATE TABLE pav_efficiency PARTITION OF PRODUCT_ATTRIBUTE_VALUES_P FOR VALUES IN (9);
28CREATE TABLE pav_power PARTITION OF PRODUCT_ATTRIBUTE_VALUES_P FOR VALUES IN (10);
29
30-- 3. default partition for other attr
31CREATE TABLE pav_default PARTITION OF PRODUCT_ATTRIBUTE_VALUES_P DEFAULT;
32
33-- insert the data
34ALTER TABLE PRODUCT_ATTRIBUTE_VALUES RENAME TO PRODUCT_ATTRIBUTE_VALUES_OLD;
35
36INSERT INTO PRODUCT_ATTRIBUTE_VALUES_P (variant_id, attribute_id, attr_value)
37SELECT variant_id, attribute_id, attr_value FROM PRODUCT_ATTRIBUTE_VALUES_OLD;
38
39ALTER TABLE PRODUCT_ATTRIBUTE_VALUES_P RENAME TO PRODUCT_ATTRIBUTE_VALUES;
40
41--======
42-- checks
43--======
44
45EXPLAIN ANALYZE SELECT * FROM product_attribute_values WHERE attribute_id = 2;
46
47SELECT
48 p.relname AS partition_name,
49 s.n_live_tup AS row_count
50FROM pg_stat_user_tables s
51JOIN pg_class p ON s.relid = p.oid
52WHERE p.relname LIKE 'pav_%'
53ORDER BY row_count DESC;
54
55SELECT
56 nmsp_parent.nspname AS parent_schema,
57 parent.relname AS parent_table,
58 nmsp_child.nspname AS partition_schema,
59 child.relname AS partition_name,
60 pg_get_expr(child.relpartbound, child.oid) AS partition_expression
61FROM pg_inherits
62JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
63JOIN pg_class child ON pg_inherits.inhrelid = child.oid
64JOIN pg_namespace nmsp_parent ON parent.relnamespace = nmsp_parent.oid
65JOIN pg_namespace nmsp_child ON child.relnamespace = nmsp_child.oid
66WHERE parent.relname = 'product_attribute_values';
67
68-- rows in partitions
69SELECT 'pav_processor' as partition, count(*) FROM pav_processor
70UNION ALL SELECT 'pav_ram', count(*) FROM pav_ram
71UNION ALL SELECT 'pav_storage', count(*) FROM pav_storage
72UNION ALL SELECT 'pav_screen_size', count(*) FROM pav_screen_size
73UNION ALL SELECT 'pav_display_type', count(*) FROM pav_display_type
74UNION ALL SELECT 'pav_battery', count(*) FROM pav_battery
75UNION ALL SELECT 'pav_gpu', count(*) FROM pav_gpu
76UNION ALL SELECT 'pav_color', count(*) FROM pav_color
77UNION ALL SELECT 'pav_efficiency', count(*) FROM pav_efficiency
78UNION ALL SELECT 'pav_power', count(*) FROM pav_power
79UNION ALL SELECT 'pav_default (Others)', count(*) FROM pav_default;
80
81
82INSERT INTO product_attribute_values (variant_id, attribute_id, attr_value)
83VALUES (9999999999, 2, '128GB');
84
85SELECT * FROM pav_ram WHERE variant_id = 9999999999;
86
87-- does new attr_id go to default
88INSERT INTO product_attribute_values (variant_id, attribute_id, attr_value)
89VALUES (9999999999, 99, 'Special_Value');
90
91SELECT * FROM pav_default WHERE variant_id = 9999999999;
92
93INSERT INTO product_attribute_values (variant_id, attribute_id, attr_value)
94VALUES (77777777, 999, 'Custom_Value');
95SELECT * FROM pav_default WHERE variant_id = 77777777;
96
97--color test
98INSERT INTO product_attribute_values (variant_id, attribute_id, attr_value)
99VALUES (88888888, 8, 'Deep Purple');
100
101SELECT * FROM pav_color WHERE variant_id = 88888888;
102EXPLAIN ANALYZE
103SELECT * FROM product_attribute_values
104WHERE attribute_id = 7 AND attr_value = 'RTX 4080';
105
106EXPLAIN ANALYZE
107SELECT * FROM product_attribute_values
108WHERE attribute_id = 8 AND attr_value = 'Silver';
109
110EXPLAIN ANALYZE
111SELECT * FROM product_attribute_values
112WHERE attr_value = 'White';
113
114SELECT
115 parent.relname AS master_table,
116 child.relname AS partition_name,
117 pg_get_expr(child.relpartbound, child.oid) AS partition_definition
118FROM pg_inherits
119JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
120JOIN pg_class child ON pg_inherits.inhrelid = child.oid
121WHERE parent.relname = 'product_attribute_values'
122ORDER BY child.relname;
123
124--======
125-- product_price_history
126--======
127
128-- new partitioned table
129CREATE TABLE PRODUCT_PRICE_HISTORY_P (
130 history_id int8 NOT NULL,
131 variant_id int8 NOT NULL,
132 old_price numeric(12, 2) NOT NULL,
133 new_price numeric(12, 2) NOT NULL,
134 change_date timestamp with time zone NOT NULL,
135 -- pk includes date
136 PRIMARY KEY (history_id, change_date)
137) PARTITION BY RANGE (change_date);
138
139
140SELECT
141 date_trunc('month', change_date) AS month_start,
142 count(*) AS num_records
143FROM myschema.product_price_history
144GROUP BY month_start
145ORDER BY month_start;
146
147-- monthly partitions
148CREATE TABLE pph_2025_05 PARTITION OF PRODUCT_PRICE_HISTORY_P FOR VALUES FROM ('2025-05-01') TO ('2025-06-01');
149CREATE TABLE pph_2025_06 PARTITION OF PRODUCT_PRICE_HISTORY_P FOR VALUES FROM ('2025-06-01') TO ('2025-07-01');
150
151
152CREATE TABLE pph_2025_07 PARTITION OF PRODUCT_PRICE_HISTORY_P FOR VALUES FROM ('2025-07-01') TO ('2025-08-01');
153CREATE TABLE pph_2025_08 PARTITION OF PRODUCT_PRICE_HISTORY_P FOR VALUES FROM ('2025-08-01') TO ('2025-09-01');
154CREATE TABLE pph_2025_09 PARTITION OF PRODUCT_PRICE_HISTORY_P FOR VALUES FROM ('2025-09-01') TO ('2025-10-01');
155CREATE TABLE pph_2025_10 PARTITION OF PRODUCT_PRICE_HISTORY_P FOR VALUES FROM ('2025-10-01') TO ('2025-11-01');
156CREATE TABLE pph_2025_11 PARTITION OF PRODUCT_PRICE_HISTORY_P FOR VALUES FROM ('2025-11-01') TO ('2025-12-01');
157CREATE TABLE pph_2025_12 PARTITION OF PRODUCT_PRICE_HISTORY_P FOR VALUES FROM ('2025-12-01') TO ('2026-01-01');
158
159
160CREATE TABLE pph_2026_01 PARTITION OF PRODUCT_PRICE_HISTORY_P FOR VALUES FROM ('2026-01-01') TO ('2026-02-01');
161CREATE TABLE pph_2026_02 PARTITION OF PRODUCT_PRICE_HISTORY_P FOR VALUES FROM ('2026-02-01') TO ('2026-03-01');
162CREATE TABLE pph_2026_03 PARTITION OF PRODUCT_PRICE_HISTORY_P FOR VALUES FROM ('2026-03-01') TO ('2026-04-01');
163CREATE TABLE pph_2026_04 PARTITION OF PRODUCT_PRICE_HISTORY_P FOR VALUES FROM ('2026-04-01') TO ('2026-05-01');
164
165CREATE TABLE pph_default PARTITION OF PRODUCT_PRICE_HISTORY_P DEFAULT;
166
167INSERT INTO PRODUCT_PRICE_HISTORY_P
168SELECT * FROM product_price_history;
169
170EXPLAIN ANALYZE
171SELECT * FROM PRODUCT_PRICE_HISTORY_P
172WHERE change_date BETWEEN '2025-11-01' AND '2025-11-30';
173
174--======
175-- product_price_history
176--======
177
178SET search_path TO myschema;
179
180-- master table
181CREATE TABLE ORDER_STATUS_HISTORY_P (
182 history_id int8 NOT NULL,
183 order_id int8 NOT NULL,
184 old_status varchar(255) NOT NULL,
185 new_status varchar(255) NOT NULL,
186 change_date timestamp with time zone NOT NULL,
187 -- pk contains date
188 PRIMARY KEY (history_id, change_date)
189) PARTITION BY RANGE (change_date);
190
191-- 2025
192CREATE TABLE osh_2025_05 PARTITION OF ORDER_STATUS_HISTORY_P FOR VALUES FROM ('2025-05-01') TO ('2025-06-01');
193CREATE TABLE osh_2025_06 PARTITION OF ORDER_STATUS_HISTORY_P FOR VALUES FROM ('2025-06-01') TO ('2025-07-01');
194CREATE TABLE osh_2025_07 PARTITION OF ORDER_STATUS_HISTORY_P FOR VALUES FROM ('2025-07-01') TO ('2025-08-01');
195CREATE TABLE osh_2025_08 PARTITION OF ORDER_STATUS_HISTORY_P FOR VALUES FROM ('2025-08-01') TO ('2025-09-01');
196CREATE TABLE osh_2025_09 PARTITION OF ORDER_STATUS_HISTORY_P FOR VALUES FROM ('2025-09-01') TO ('2025-10-01');
197CREATE TABLE osh_2025_10 PARTITION OF ORDER_STATUS_HISTORY_P FOR VALUES FROM ('2025-10-01') TO ('2025-11-01');
198CREATE TABLE osh_2025_11 PARTITION OF ORDER_STATUS_HISTORY_P FOR VALUES FROM ('2025-11-01') TO ('2025-12-01');
199CREATE TABLE osh_2025_12 PARTITION OF ORDER_STATUS_HISTORY_P FOR VALUES FROM ('2025-12-01') TO ('2026-01-01');
200
201-- 2026
202CREATE TABLE osh_2026_01 PARTITION OF ORDER_STATUS_HISTORY_P FOR VALUES FROM ('2026-01-01') TO ('2026-02-01');
203CREATE TABLE osh_2026_02 PARTITION OF ORDER_STATUS_HISTORY_P FOR VALUES FROM ('2026-02-01') TO ('2026-03-01');
204CREATE TABLE osh_2026_03 PARTITION OF ORDER_STATUS_HISTORY_P FOR VALUES FROM ('2026-03-01') TO ('2026-04-01');
205CREATE TABLE osh_2026_04 PARTITION OF ORDER_STATUS_HISTORY_P FOR VALUES FROM ('2026-04-01') TO ('2026-05-01');
206
207-- DEFAULT
208CREATE TABLE osh_default PARTITION OF ORDER_STATUS_HISTORY_P DEFAULT;
209
210INSERT INTO ORDER_STATUS_HISTORY_P
211SELECT * FROM order_status_history;
212
213ALTER TABLE order_status_history RENAME TO order_status_history_old;
214ALTER TABLE ORDER_STATUS_HISTORY_P RENAME TO order_status_history;
215
216--check
217
218EXPLAIN ANALYZE
219SELECT * FROM order_status_history
220WHERE order_id = 1789
221 AND change_date >= '2025-06-14'
222 AND change_date < '2025-07-01'
223 AND old_status <> 'CART';