pet*_*erh 4 postgresql primary-key
我想转储一个表的全部内容,按主键排序。直觉上,我想做一个
SELECT * FROM %table_name% ORDER BY %primary_key_of(table_name)%;
Run Code Online (Sandbox Code Playgroud)
这将由外部工具运行,知道表的列表,但不知道它们的主键。
如果没有更好的选择,我们可以假设所有的主键都是单列的。
我使用的是 PostgreSQL-9.5,但可以升级。
默认情况下, simpleSELECT * FROM %table_name%不会按主键对结果进行排序。
但是您可以获得表的主键列列表:
SELECT ind_column.attname AS columns_of_pk
FROM pg_class tbl
INNER JOIN pg_index ind ON ind.indrelid = tbl.oid
INNER JOIN pg_class ind_table ON ind_table.oid = ind.indexrelid
INNER JOIN pg_attribute ind_column ON ind_column.attrelid = ind_table.oid
WHERE tbl.relname = 'my_table'
AND ind.indisprimary;
Run Code Online (Sandbox Code Playgroud)
然后在ORDER BY子句中使用此列构建动态查询。
如果在不同模式中有多个同名表,请添加INNER JOIN pg_namespace sch ON sch.oid = tbl.relnamespace并设置WHERE条件sch.nspname。
您可以在 1 个查询中获取所有表的 PK:
SELECT sch.nspname AS "schema"
, tbl.relname AS "table"
, array_agg(ind_column.attname) AS columns_of_pk
FROM pg_class tbl
INNER JOIN pg_namespace sch ON sch.oid = tbl.relnamespace
INNER JOIN pg_index ind ON ind.indrelid = tbl.oid
INNER JOIN pg_class ind_table ON ind_table.oid = ind.indexrelid
INNER JOIN pg_attribute ind_column ON ind_column.attrelid = ind_table.oid
WHERE sch.nspname <> 'pg_toast'
AND ind.indisprimary
GROUP BY "schema", "table";
Run Code Online (Sandbox Code Playgroud)
我相信如果你在主键上放置聚集索引,那么 PG 将默认使用它。未经检验的假设:)
CLUSTER table_name USING primary_key_index;
Run Code Online (Sandbox Code Playgroud)
根据https://www.postgresql.org/docs/current/static/sql-cluster.html
如果您随机访问表中的单行,则表中数据的实际顺序并不重要。但是,如果您倾向于比其他数据更频繁地访问某些数据,并且有一个索引将它们分组在一起,那么您将从使用 CLUSTER 中受益。如果您要从表中请求一系列索引值,或者请求具有多个匹配行的单个索引值,则 CLUSTER 将有所帮助,因为一旦索引识别出匹配的第一行的表页,则所有其他匹配的行都可能是已经在同一个表页上,因此您可以节省磁盘访问并加快查询速度。
CLUSTER 可以使用指定索引上的索引扫描或(如果索引是 B 树)顺序扫描然后排序来对表重新排序。它将尝试根据规划器成本参数和可用的统计信息选择更快的方法。
| 归档时间: |
|
| 查看次数: |
5919 次 |
| 最近记录: |