Tee*_*jay 1 sql postgresql indexing ddl
Postgres 方法array_position(array, element)与 SQL 中的其他事物一样,是基于 1 的。例如:
SELECT array_position(array[4,5,6], 5) -- returns 2
Run Code Online (Sandbox Code Playgroud)
但是,我正在执行以下查询来从 pg_catalog 检索非唯一索引及其列:
SELECT array_position(array[4,5,6], 5) -- returns 2
Run Code Online (Sandbox Code Playgroud)
第四个选择indkey在数组中搜索列的ordinal_position,因此对于每一列,它都会获取其在索引中的位置。
有趣的是,第一列的位置为 0,所以我必须添加+ 1它以使其基于 1。
随后的CASE表达式使用完全相同的值作为检索 的第 n 个元素的索引indoption,奇怪的是,即使[]运算符也是基于 1 的,也能正常工作:
SELECT (array[4,5,6])[2] -- returns 5
Run Code Online (Sandbox Code Playgroud)
这怎么样?
我目前使用的是 PG 9.6。
你说:
Postgres 方法
array_position(array, element)与 SQL 中的其他事物一样,是基于 1 的。
但这是微妙错误的。Postgres 数组默认从1 开始。但 Postgres 允许任何范围的整数作为索引。而且该函数array_position()不是基于任何东西的。它只是返回找到的索引。
SELECT array_position('[7:9]={4,5,6}'::int[], 5); -- returns 8!
Run Code Online (Sandbox Code Playgroud)
看:
并且一开始pg_index.indkey就不是一个数组。它的 typeint2vector是内部类型,不可用于一般用途,并且是基于 0 的!它允许下标(类似于数组)。int2[]保留从 0 开始的数组下标(索引)的强制转换。
无论哪种方式,您的查询似乎都不正确。
on消除存储在默认表空间中的索引INNER JOIN。手册上:pg_tablespacepg_class.reltablespace
如果为零,则隐含数据库的默认表空间。
pg_tablespace但with中没有条目oid = 0,因此将其设为 a LEFT JOIN。
如果您尝试手动提取部分索引定义,则会出现更多警告。你所拥有的ASC/DESC并没有完全解决它。看:
而你根本就没有考虑过NULLS FIRST | LAST。WHERE或者部分索引的可能条件,...
我强烈建议使用内置系统目录信息功能 pg_get_indexdef()进行这种简单、快速且可靠的替代方案:
SELECT array_position('[7:9]={4,5,6}'::int[], 5); -- returns 8!
Run Code Online (Sandbox Code Playgroud)
重构索引的创建命令。(这是反编译重建,不是命令原文。)
这使得所有方面都正确,并且可以跨 Postgres 版本保持工作。
如果你坚持分解索引定义,这个查询基本上应该可以工作(从 Postgres 14 开始):
SELECT ci.relname AS index_name
, ix.indrelid::regclass::text AS table_name
, pg_get_indexdef (ix.indexrelid) AS idx_def
FROM pg_catalog.pg_index ix
JOIN pg_catalog.pg_class ci ON ci.oid = ix.indexrelid
JOIN pg_catalog.pg_namespace ns ON ns.oid = ci.relnamespace
WHERE ix.indisunique = false
AND ns.nspname = 'my_schema'
ORDER BY 2, 1;
Run Code Online (Sandbox Code Playgroud)
但“正确的查询”要稳定可靠得多。
特别是,我使用unnest()多个参数来取消嵌套indkey,indoption并以锁步方式使用序数(从 1 开始)位置。看:
关于WITH ORDINALITY:
我用来pg_get_indexdef()重建每个索引字段。这还涵盖表达式,而不仅仅是普通表列。
我添加了direction_nulls指示NULLS FIRST | LAST,请参阅:
并where_clause带有WHERE部分索引的反编译子句(使用pg_get_expr())。
| 归档时间: |
|
| 查看次数: |
1259 次 |
| 最近记录: |