CREATETABLE clstr_tst_s (rf_a SERIAL PRIMARYKEY,
b INT);
CREATETABLE clstr_tst (a SERIAL PRIMARYKEY,
b INT,
c TEXT,
d TEXT, CONSTRAINT clstr_tst_con FOREIGNKEY (b) REFERENCES clstr_tst_s);
CREATEINDEX clstr_tst_b ON clstr_tst (b); CREATEINDEX clstr_tst_c ON clstr_tst (c); CREATEINDEX clstr_tst_c_b ON clstr_tst (c,b); CREATEINDEX clstr_tst_b_c ON clstr_tst (b,c);
INSERTINTO clstr_tst_s (b) VALUES (0); INSERTINTO clstr_tst_s (b) SELECT b FROM clstr_tst_s; INSERTINTO clstr_tst_s (b) SELECT b FROM clstr_tst_s; INSERTINTO clstr_tst_s (b) SELECT b FROM clstr_tst_s; INSERTINTO clstr_tst_s (b) SELECT b FROM clstr_tst_s; INSERTINTO clstr_tst_s (b) SELECT b FROM clstr_tst_s;
INSERTINTO clstr_tst (b, c) VALUES (11, 'once'); INSERTINTO clstr_tst (b, c) VALUES (10, 'diez'); INSERTINTO clstr_tst (b, c) VALUES (31, 'treinta y uno'); INSERTINTO clstr_tst (b, c) VALUES (22, 'veintidos'); INSERTINTO clstr_tst (b, c) VALUES (3, 'tres'); INSERTINTO clstr_tst (b, c) VALUES (20, 'veinte'); INSERTINTO clstr_tst (b, c) VALUES (23, 'veintitres'); INSERTINTO clstr_tst (b, c) VALUES (21, 'veintiuno'); INSERTINTO clstr_tst (b, c) VALUES (4, 'cuatro'); INSERTINTO clstr_tst (b, c) VALUES (14, 'catorce'); INSERTINTO clstr_tst (b, c) VALUES (2, 'dos'); INSERTINTO clstr_tst (b, c) VALUES (18, 'dieciocho'); INSERTINTO clstr_tst (b, c) VALUES (27, 'veintisiete'); INSERTINTO clstr_tst (b, c) VALUES (25, 'veinticinco'); INSERTINTO clstr_tst (b, c) VALUES (13, 'trece'); INSERTINTO clstr_tst (b, c) VALUES (28, 'veintiocho'); INSERTINTO clstr_tst (b, c) VALUES (32, 'treinta y dos'); INSERTINTO clstr_tst (b, c) VALUES (5, 'cinco'); INSERTINTO clstr_tst (b, c) VALUES (29, 'veintinueve'); INSERTINTO clstr_tst (b, c) VALUES (1, 'uno'); INSERTINTO clstr_tst (b, c) VALUES (24, 'veinticuatro'); INSERTINTO clstr_tst (b, c) VALUES (30, 'treinta'); INSERTINTO clstr_tst (b, c) VALUES (12, 'doce'); INSERTINTO clstr_tst (b, c) VALUES (17, 'diecisiete'); INSERTINTO clstr_tst (b, c) VALUES (9, 'nueve'); INSERTINTO clstr_tst (b, c) VALUES (19, 'diecinueve'); INSERTINTO clstr_tst (b, c) VALUES (26, 'veintiseis'); INSERTINTO clstr_tst (b, c) VALUES (15, 'quince'); INSERTINTO clstr_tst (b, c) VALUES (7, 'siete'); INSERTINTO clstr_tst (b, c) VALUES (16, 'dieciseis'); INSERTINTO clstr_tst (b, c) VALUES (8, 'ocho'); -- This entry is needed to test that TOASTED values are copied correctly. INSERTINTO clstr_tst (b, c, d) VALUES (6, 'seis', repeat('xyzzy', 100000));
CLUSTER clstr_tst_c ON clstr_tst;
SELECT a,b,c,substring(d for30), length(d) from clstr_tst; SELECT a,b,c,substring(d for30), length(d) from clstr_tst ORDERBY a; SELECT a,b,c,substring(d for30), length(d) from clstr_tst ORDERBY b; SELECT a,b,c,substring(d for30), length(d) from clstr_tst ORDERBY c;
-- Verify that inheritance link still works INSERTINTO clstr_tst_inh VALUES (0, 100, 'in child table'); SELECT a,b,c,substring(d for30), length(d) from clstr_tst;
-- Verify that foreign key link still works INSERTINTO clstr_tst (b, c) VALUES (1111, 'this should fail');
SELECT conname FROM pg_constraint WHERE conrelid = 'clstr_tst'::regclass ORDERBY1;
SELECT relname, relkind, EXISTS(SELECT1FROM pg_class WHERE oid = c.reltoastrelid) AS hastoast FROM pg_class c WHERE relname LIKE'clstr_tst%'ORDERBY relname;
-- Verify that indisclustered is correctly set SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2 WHERE pg_class.oid=indexrelid AND indrelid=pg_class_2.oid AND pg_class_2.relname = 'clstr_tst' AND indisclustered;
-- Try changing indisclustered ALTERTABLE clstr_tst CLUSTER ON clstr_tst_b_c; SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2 WHERE pg_class.oid=indexrelid AND indrelid=pg_class_2.oid AND pg_class_2.relname = 'clstr_tst' AND indisclustered;
-- Try turning off all clustering ALTERTABLE clstr_tst SET WITHOUT CLUSTER; SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2 WHERE pg_class.oid=indexrelid AND indrelid=pg_class_2.oid AND pg_class_2.relname = 'clstr_tst' AND indisclustered;
-- Verify that toast tables are clusterable
CLUSTER pg_toast.pg_toast_826 USING pg_toast_826_index;
-- Verify that clustering all tables does in fact cluster the right ones CREATE USER regress_clstr_user; CREATETABLE clstr_1 (a INTPRIMARYKEY); CREATETABLE clstr_2 (a INTPRIMARYKEY); CREATETABLE clstr_3 (a INTPRIMARYKEY); ALTERTABLE clstr_1 OWNER TO regress_clstr_user; ALTERTABLE clstr_3 OWNER TO regress_clstr_user; GRANTSELECTON clstr_2 TO regress_clstr_user; INSERTINTO clstr_1 VALUES (2); INSERTINTO clstr_1 VALUES (1); INSERTINTO clstr_2 VALUES (2); INSERTINTO clstr_2 VALUES (1); INSERTINTO clstr_3 VALUES (2); INSERTINTO clstr_3 VALUES (1);
-- "CLUSTER <tablename>" on a table that hasn't been clustered
CLUSTER clstr_2;
CLUSTER clstr_1_pkey ON clstr_1;
CLUSTER clstr_2 USING clstr_2_pkey; SELECT * FROM clstr_1 UNIONALL SELECT * FROM clstr_2 UNIONALL SELECT * FROM clstr_3;
-- revert to the original state DELETEFROM clstr_1; DELETEFROM clstr_2; DELETEFROM clstr_3; INSERTINTO clstr_1 VALUES (2); INSERTINTO clstr_1 VALUES (1); INSERTINTO clstr_2 VALUES (2); INSERTINTO clstr_2 VALUES (1); INSERTINTO clstr_3 VALUES (2); INSERTINTO clstr_3 VALUES (1);
-- this user can only cluster clstr_1 and clstr_3, but the latter -- has not been clustered SET SESSION AUTHORIZATION regress_clstr_user; SET client_min_messages = ERROR; -- order of "skipping" warnings may vary
CLUSTER;
RESET client_min_messages; SELECT * FROM clstr_1 UNIONALL SELECT * FROM clstr_2 UNIONALL SELECT * FROM clstr_3;
-- cluster a single table using the indisclustered bit previously set DELETEFROM clstr_1; INSERTINTO clstr_1 VALUES (2); INSERTINTO clstr_1 VALUES (1);
CLUSTER clstr_1; SELECT * FROM clstr_1;
-- Test MVCC-safety of cluster. There isn't much we can do to verify the -- results with a single backend...
SELECT * FROM clustertest;
CLUSTER clustertest_pkey ON clustertest; SELECT * FROM clustertest;
COMMIT;
SELECT * FROM clustertest;
-- check that temp tables can be clustered create temp table clstr_temp (col1 intprimarykey, col2 text); insertinto clstr_temp values (2, 'two'), (1, 'one');
cluster clstr_temp using clstr_temp_pkey; select * from clstr_temp; droptable clstr_temp;
RESET SESSION AUTHORIZATION;
-- check clustering an empty table DROPTABLE clustertest; CREATETABLE clustertest (f1 intPRIMARYKEY);
CLUSTER clustertest USING clustertest_pkey;
CLUSTER clustertest;
-- Check that partitioned tables can be clustered CREATETABLE clstrpart (a int) PARTITION BY RANGE (a); CREATETABLE clstrpart1 PARTITION OF clstrpart FORVALUESFROM (1) TO (10) PARTITION BY RANGE (a); CREATETABLE clstrpart11 PARTITION OF clstrpart1 FORVALUESFROM (1) TO (5); CREATETABLE clstrpart12 PARTITION OF clstrpart1 FORVALUESFROM (5) TO (10) PARTITION BY RANGE (a); CREATETABLE clstrpart2 PARTITION OF clstrpart FORVALUESFROM (10) TO (20); CREATETABLE clstrpart3 PARTITION OF clstrpart DEFAULT PARTITION BY RANGE (a); CREATETABLE clstrpart33 PARTITION OF clstrpart3 DEFAULT; CREATEINDEX clstrpart_only_idx ON ONLY clstrpart (a);
CLUSTER clstrpart USING clstrpart_only_idx; -- fails DROPINDEX clstrpart_only_idx; CREATEINDEX clstrpart_idx ON clstrpart (a); -- Check that clustering sets new relfilenodes: CREATE TEMP TABLE old_cluster_info ASSELECT relname, level, relfilenode, relkind FROM pg_partition_tree('clstrpart'::regclass) AS tree JOIN pg_class c ON c.oid=tree.relid ;
CLUSTER clstrpart USING clstrpart_idx; CREATE TEMP TABLE new_cluster_info ASSELECT relname, level, relfilenode, relkind FROM pg_partition_tree('clstrpart'::regclass) AS tree JOIN pg_class c ON c.oid=tree.relid ; SELECT relname, old.level, old.relkind, old.relfilenode = new.relfilenode FROM old_cluster_info AS old JOIN new_cluster_info AS new USING (relname) ORDERBY relname COLLATE"C"; -- Partitioned indexes aren't and can't be marked un/clustered:
\d clstrpart
CLUSTER clstrpart; ALTERTABLE clstrpart SET WITHOUT CLUSTER; ALTERTABLE clstrpart CLUSTER ON clstrpart_idx; DROPTABLE clstrpart;
-- Ownership of partitions is checked CREATETABLE ptnowner(i intunique) PARTITION BY LIST (i); CREATEINDEX ptnowner_i_idx ON ptnowner(i); CREATETABLE ptnowner1 PARTITION OF ptnowner FORVALUESIN (1); CREATE ROLE regress_ptnowner; CREATETABLE ptnowner2 PARTITION OF ptnowner FORVALUESIN (2); ALTERTABLE ptnowner1 OWNER TO regress_ptnowner; SET SESSION AUTHORIZATION regress_ptnowner;
CLUSTER ptnowner USING ptnowner_i_idx;
RESET SESSION AUTHORIZATION; ALTERTABLE ptnowner OWNER TO regress_ptnowner; CREATE TEMP TABLE ptnowner_oldnodes AS SELECT oid, relname, relfilenode FROM pg_partition_tree('ptnowner') AS tree JOIN pg_class AS c ON c.oid=tree.relid; SET SESSION AUTHORIZATION regress_ptnowner;
CLUSTER ptnowner USING ptnowner_i_idx;
RESET SESSION AUTHORIZATION; SELECT a.relname, a.relfilenode=b.relfilenode FROM pg_class a JOIN ptnowner_oldnodes b USING (oid) ORDERBY a.relname COLLATE"C"; DROPTABLE ptnowner; DROP ROLE regress_ptnowner;
-- Test CLUSTER with external tuplesorting
createtable clstr_4 asselect * from tenk1; createindex cluster_sort on clstr_4 (hundred, thousand, tenthous); -- ensure we don't use the index in CLUSTER nor the checking SELECTs set enable_indexscan = off;
-- Use external sort: set maintenance_work_mem = '1MB';
cluster clstr_4 using cluster_sort; select * from
(select hundred, lag(hundred) over () as lhundred,
thousand, lag(thousand) over () as lthousand,
tenthous, lag(tenthous) over () as ltenthous from clstr_4) ss where row(hundred, thousand, tenthous) <= row(lhundred, lthousand, ltenthous);
-- test CLUSTER on expression index CREATETABLE clstr_expression(id serial primarykey, a int, b text COLLATE"C"); INSERTINTO clstr_expression(a, b) SELECT g.i % 42, 'prefix'||g.i FROM generate_series(1, 133) g(i); CREATEINDEX clstr_expression_minus_a ON clstr_expression ((-a), b); CREATEINDEX clstr_expression_upper_b ON clstr_expression ((upper(b)));
-- verify indexes work before cluster
BEGIN; SET LOCAL enable_seqscan = false; EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'; SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'; EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE -a = -3ORDERBY -a, b; SELECT * FROM clstr_expression WHERE -a = -3ORDERBY -a, b; COMMIT;
-- and after clustering on clstr_expression_minus_a
CLUSTER clstr_expression USING clstr_expression_minus_a; WITH rows AS
(SELECT ctid, lag(a) OVER (ORDERBY ctid) AS la, a FROM clstr_expression) SELECT * FROM rows WHERE la < a;
BEGIN; SET LOCAL enable_seqscan = false; EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'; SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'; EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE -a = -3ORDERBY -a, b; SELECT * FROM clstr_expression WHERE -a = -3ORDERBY -a, b; COMMIT;
-- and after clustering on clstr_expression_upper_b
CLUSTER clstr_expression USING clstr_expression_upper_b; WITH rows AS
(SELECT ctid, lag(b) OVER (ORDERBY ctid) AS lb, b FROM clstr_expression) SELECT * FROM rows WHERE upper(lb) > upper(b);
BEGIN; SET LOCAL enable_seqscan = false; EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'; SELECT * FROM clstr_expression WHERE upper(b) = 'PREFIX3'; EXPLAIN (COSTS OFF) SELECT * FROM clstr_expression WHERE -a = -3ORDERBY -a, b; SELECT * FROM clstr_expression WHERE -a = -3ORDERBY -a, b; COMMIT;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.