You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
DO $$
DECLARE
count bigint;
unique_count bigint;
row record;
BEGIN
CREATE TEMPORARY TABLE hash_index_candidates (
table_name text,
index_name text, -- b-tree index to migrate
column_name text,
unique_ratio decimal,
btree_index_size text,
potential_hash_index_size text, -- assumption based value
count bigint
); -- stores temporary results for the current session
FOR row IN (
SELECTt.table_nameAS table_name,
t.index_nameAS index_name,
t.column_nameAS column_name,
pg_size_pretty(t.size) AS index_size
FROM
(
SELECTtab.relnameAS table_name,
cls.relnameAS index_name,
pa.attnameAS column_name,
pg_relation_size(cls.relname :: text) AS size
FROM pg_stat_user_indexes idx
JOIN pg_index pi ONpi.indexrelid=idx.indexrelidJOIN pg_class cls ONcls.oid=idx.indexrelidJOIN pg_class tab ONtab.oid=idx.relidJOIN pg_am am ONam.oid=cls.relamJOIN pg_attribute pa ONcls.oid=pa.attrelidJOIN pg_type pt ONpa.atttypid=pt.oidWHERE amname ='btree'-- b-tree typeAND indnatts =1-- index covers single columnAND indislive = true -- check index "health"AND indisvalid = true -- check index "health"AND indpred IS NULL-- index has no conditionsAND typname IN ('varchar', 'text', 'char')
AND indisprimary = false -- index is not primaryAND typlen =-1-- type has unlimited bytes lengthAND indisunique = false -- index is not unique
) t
WHEREt.size>104857600-- index size is more than 100MB
) LOOP
EXECUTE format('SELECT COUNT(%I) FROM %I', row.column_name, row.table_name ) INTO count;
EXECUTE format('SELECT COUNT(DISTINCT %I) FROM %I', row.column_name, row.table_name) INTO unique_count;
INSERT INTO hash_index_candidates
VALUES
(
row.table_name,
row.index_name,
row.column_name,
round(unique_count :: decimal/ (count :: decimal+1) *100, 2),
row.index_size,
pg_size_pretty(count /300*8192), -- assumes 300 tuples per hash bucket
count
);
END LOOP;
END
$$ LANGUAGE plpgsql;
SELECT*FROM hash_index_candidates WHERE unique_ratio >95; -- fetch results
First, we should check if the candidate satisfies the rule of thumb we came up with here:
Values have high cardinality. Ideally, their hash codes have high cardinality as well;
Values are queried only with equality operators;
Values lengths should be at least 25 characters long.
The most important part is the usage of the index. If you’re confident that your field under the index is queried by equality operators only, then go ahead and migrate.
The text was updated successfully, but these errors were encountered:
Take a look at
The text was updated successfully, but these errors were encountered: