关于postgres中的聚簇索引

twi*_*imo 38 postgresql clustered-index

我正在使用psql访问postgres数据库.查看表的元数据时,有没有办法查看表的索引是否为聚簇索引?

我听说表的PRIMARY KEY自动与聚簇索引相关联,是真的吗?

ara*_*nid 34

请注意,PostgreSQL使用术语"聚集索引"来使用与SQL Server模糊相似但又非常不同的东西.

如果某个特定索引已被指定为表\d的聚簇索引,则psql的命令将指示聚簇索引,例如,

Indexes:
    "timezone_description_pkey" PRIMARY KEY, btree (timezone) CLUSTER
Run Code Online (Sandbox Code Playgroud)

默认情况下,PostgreSQL不会将索引指定为聚类索引.它也不会自动排列表数据以与聚集索引相关联,即使这样提名:必须使用CLUSTER命令来重新组织表数据.

  • 准确地说,Postgres *根本*不使用术语“聚集索引”。在“CLUSTER”运行之后,就会出现“聚集表”。 (12认同)

bel*_*daz 21

在PostgreSQL中,clustered属性保存在相应索引的元数据中,而不是关系本身.它是pg_index目录中的indisclustered属性.但请注意,postgres中的聚类关系是一次性操作:即使该属性为true,对表的更新也不会保持数据的排序特性.迄今为止,数据集群的自动维护仍然是一种流行的TODO项目.

经常有混淆集群综合指标,特别是因为流行的教科书使用冲突的名称,术语又是在不同的Postgres和SQL服务器(仅举二)的手册.当我谈到一个集成索引(也称为主索引主索引)我的意思是一种其中的关系的数据被包含在索引的叶子,而不是一个外部辅助在该叶片包含指向索引条目索引到表记录.前一种类型必须始终聚集.不幸的是,postgres只支持后一种类型.无论如何,集成(主)索引总是聚集的事实可能已经产生了这样的信念,即"表的主键自动与聚簇索引相关联".这两个陈述听起来很相似,但却不同.

  • 我相信SQL Server默认情况下也会让主键使用聚集索引,除非你另有说明,对吧?这可能会导致混乱或导致假设两者必然意味着同一件事。 (4认同)
  • 是的,根据http://msdn.microsoft.com/en-us/library/ms174979.aspx“主键约束默认为聚集,唯一约束默认为非聚集。” (3认同)

a_h*_*ame 18

有没有办法看看表的索引是否是聚簇索引

PostgreSQL没有聚集索引,因此您将无法看到它们.

我听说表的PRIMARY KEY自动与聚簇索引相关联,是真的吗?

不,那不是真的(见上文)

您可以手动在索引中对表进行集群,但这不会自动维护(例如,使用SQL Server的聚簇索引).

有关更多详细信息,请参阅手册中CLUSTER命令的说明.


Anv*_*esh 12

PostgreSQL没有像Microsoft SQL Server那样直接实现CLUSTER索引.

参考摘自此博客:

在PostgreSQL中,我们有一个类似于Cluster Index的CLUSTER命令.

创建表主键或任何其他索引后,可以通过指定索引名称来执行CLUSTER命令,以实现表数据的物理顺序.

当表被聚类时,它将根据索引信息进行物理重新排序.群集是一次性操作:随后更新表时,更改不会群集.也就是说,不会尝试根据其索引顺序存储新行或更新的行.

集群语法:

第一次必须使用索引名称执行CLUSTER.

CLUSTER table_name USING index_name;
Run Code Online (Sandbox Code Playgroud)

集群表:

一旦使用Index执行了CLUSTER,下次只应执行CLUSTER TABLE,因为它知道哪个索引已经定义为CLUSTER.

CLUSTER table_name;
Run Code Online (Sandbox Code Playgroud)


小智 12


集群索引

簇索引意味着告诉数据库将实际接近的接近值存储在磁盘上。它们可以唯一标识 SQL 表中的行。每张表都可以有一个一一的聚集索引。一个簇索引可以覆盖多列。默认情况下,具有主键的列已经具有聚集索引。

字典

字典本身就是一个带有聚集索引的表。因为所有数据都是按字母顺序物理存储的。


非集群索引

非聚集索引就像是一本书的简单索引。它们仅用于快速检索数据。不确定是否有唯一数据。非聚集索引包含非聚集索引键和它们对应的数据位置指针。例如,一本书的内容索引包含主题或章节的关键字及其页面位置。

图书内容索引

一本书的内容表包含内容名称及其页面位置。不确定数据是否唯一。因为可以多次放置相同的段落或文本行或单词。


PostgreSQL 索引

PostgreSQL 自动为表的PRIMARY KEY每个UNIQUE约束创建索引。在 PostgreSQL 终端中登录数据库并键入 \d table_name. 所有存储的索引都将被可视化。如果有聚集索引,那么它也将被识别。

创建表

CREATE TABLE IF NOT EXISTS profile(
    uid serial NOT NULL UNIQUE PRIMARY KEY,
    username varchar(30) NOT NULL UNIQUE,
    phone varchar(11) NOT NULL UNIQUE,
    age smallint CHECK(age>12),
    address text NULL
);
Run Code Online (Sandbox Code Playgroud)

3 索引将自动创建。所有这些索引都是非聚集的

"profile_pkey" PRIMARY KEY, btree (uid)
"profile_phone_key" UNIQUE CONSTRAINT, btree (phone)
"profile_username_key" UNIQUE CONSTRAINT, btree (username)
Run Code Online (Sandbox Code Playgroud)

使用 uid 和 username 创建我们自己的索引

"profile_pkey" PRIMARY KEY, btree (uid)
"profile_phone_key" UNIQUE CONSTRAINT, btree (phone)
"profile_username_key" UNIQUE CONSTRAINT, btree (username)
Run Code Online (Sandbox Code Playgroud)

这实际上创建了一个非聚集索引。要使其群集,请运行下一部分。

将非聚集索引转换为聚集索引

CREATE INDEX profile_index ON profile(uid, username);
Run Code Online (Sandbox Code Playgroud)

检查表\d profile。它会是这样的:

                                     Table "public.profile"
  Column  |         Type          | Collation | Nullable |               Default
----------+-----------------------+-----------+----------+--------------------------------------
 uid      | integer               |           | not null | nextval('profile_uid_seq'::regclass)
 username | character varying(30) |           | not null |
 phone    | character varying(11) |           | not null |
 age      | smallint              |           |          |
 address  | text                  |           |          |
Indexes:
    "profile_pkey" PRIMARY KEY, btree (uid)
    "profile_phone_key" UNIQUE CONSTRAINT, btree (phone)
    "profile_username_key" UNIQUE CONSTRAINT, btree (username)
    "profile_index" btree (uid, username) CLUSTER
Check constraints:
    "profile_age_check" CHECK (age > 12)
Run Code Online (Sandbox Code Playgroud)

请注意,profile_index 现在是“CLUSTER”

现在,重新对表进行集群,以便该表可以遵循集群索引角色

ALTER TABLE profile CLUSTER ON profile_index;
Run Code Online (Sandbox Code Playgroud)

  • 这似乎混淆了 PostgreSQL 和 SQL Server 中集群的不同概念。 (5认同)

seb*_*seb 6

如果您想知道给定的表是否CLUSTER使用 SQL 编辑,您可以使用以下查询来显示正在使用的索引(在 Postgres 9.5 和 9.6 版中测试):

SELECT
  i.relname AS index_for_cluster
FROM
  pg_index AS idx
JOIN
  pg_class AS i
ON
  i.oid = idx.indexrelid
WHERE
  idx.indisclustered
  AND idx.indrelid::regclass = 'your_table_name'::regclass;
Run Code Online (Sandbox Code Playgroud)