Recently came to know about the gpreload utility. It helps to reload
table data in sorted order based on user specified columns (kind of
similar to CLUSTER though with some difference we will discuss later).
The main use case for the utility is for append-optimized tables with
compression enabled. Reloading the data to get better compression by
resorting and repacking data with new/old attributes. Also helps to
improve query performance as a result. Plus, helps to save (or
reclaim) disk space by optimizing compression for mostly now static
tables in the system.
The utility takes as input a file where it can specify schema qualified
table names to reload and columns to be used for sorting.
High-level gpreload utility flow for each table:
1. BEGIN;
2. CREATE TEMP TABLE <tmp_table> AS SELECT * FROM <src_table>;
3. SELECT COUNT(*) from <src_table>; -- just for some unsuitable checking
4. SELECT COUNT(*) from <tmp_table>; -- just for some unsuitable checking
5. TRUNCATE TABLE <src_table>;
6. INSERT INTO <src_table> SELECT * FROM <tmp_table> ORDER BY {user_specified_column_list};
7. COMMIT;
Utility has following limitations:
- Table is scanned multiple times by the utility
- Race condition exist and hence may cause data loss if new data is
inserted into table after creating temp table and before truncating
actual table
- Wildcard characters are not supported in object names
- Zero (now at least some thanks to Ed and Abhijeet) test coverage
- It's a utility in Python and not SQL command
- Double the size of table free disk space required for the operation
(temp table and new table), as the truncate is inside the transaction, old
data is deleted only after commit.
I played with it and am convinced it should be deprecated for GPDB7.
Given its very useful functionality, we should replace it with SQL command:
ALTER TABLE <name> WITH (REORGANIZE=true) ORDER BY clause.
This can be implemented very similarly to how changing table's
distribution is implemented currently.
CLUSTER command has some similarities but doesn't cover the full
use case as index is must for the cluster to work whereas not for gpreload
utility. Also, the database currently doesn't remember the columns on
which the table is sorted.
Future potential enhancements to this command (delivered in iterations)
may be to allow altering storage types like row to column or
compression type or to a foreign table.
Thoughts?
--