web-dev-qa-db-ja.com

postgresのクラスター化インデックスについて

私はpsqlを使用してpostgresデータベースにアクセスしています。テーブルのメタデータを表示するときに、テーブルのインデックスがクラスター化インデックスであるかどうかを確認する方法はありますか?

テーブルのプライマリキーがクラスター化インデックスに自動的に関連付けられていると聞きましたが、本当ですか?

37
twimo

PostgreSQLでは、「クラスター化インデックス」という用語を使用して、SQL Serverとはあいまいに似ているが非常に異なるものを使用していることに注意してください。

特定のインデックスがテーブルのクラスタリングインデックスとして指定されている場合、psqlの\dコマンドは、クラスター化インデックスを示します。

Indexes:
    "timezone_description_pkey" PRIMARY KEY, btree (timezone) CLUSTER

PostgreSQLは、デフォルトではクラスタリングインデックスとしてインデックスを指定しません。また、指定された場合でも、クラスタ化インデックスと相関するようにテーブルデータを自動的に配置しません。テーブルデータを再編成するには、CLUSTERコマンドを使用する必要があります。

34
araqnid

PostgreSQLでは、クラスター化された属性は、リレーション自体ではなく、対応するインデックスのメタデータに保持されます。 pg_index カタログのindisclustered属性です。ただし、postgres内のクラスタリング関係は1回限りのアクションであることに注意してください。属性がtrueであっても、テーブルの更新はデータのソートされた性質を維持しません。現在まで、データクラスタリングの自動メンテナンスは、人気のある [〜#〜] todo [〜#〜] 項目のままです。

clusteredintegratedインデックスの間にはしばしば混乱があります。教科書は相反する名前を使用し、用語はpostgresとSQLサーバーのマニュアルで再び異なります(2つだけを挙げると)。 integrated indexmain indexまたはprimary indexexternalまたはsecondaryとは対照的に、関係データがインデックスの葉に含まれているものを意味しますテーブルレコードを指すインデックスエントリが葉に含まれるインデックス。前者のタイプは、常にクラスター化されています。残念ながら、postgresは後者のタイプのみをサポートしています。とにかく、統合(プライマリ)インデックスが常にクラスター化されるという事実は、「テーブルのプライマリキーがクラスター化インデックスに自動的に関連付けられる」という信念を生じさせた可能性があります。 2つのステートメントは似ていますが、異なっています。

20
beldaz

テーブルのインデックスがクラスタ化インデックスであるかどうかを確認する方法はありますか

PostgreSQLにはクラスター化インデックスがないため、それらを表示することはできません。

テーブルのプライマリキーがクラスター化インデックスに自動的に関連付けられていると聞きましたが、本当ですか?

いいえ、それは真実ではありません(上記参照)

インデックスに沿ってテーブルを手動でクラスター化できますが、これは自動的に維持されるものではありません(SQL Serverのクラスター化インデックスなど)。

詳細については、マニュアルの [〜#〜] cluster [〜#〜] コマンドの説明を参照してください。

18

PostgreSQLには、Microsoft SQL ServerのようなCLUSTERインデックスの直接実装はありません。

このブログから引用したリファレンス:

PostgreSQLには、クラスターインデックスに似た1つのCLUSTERコマンドがあります。

テーブルの主キーまたはその他のインデックスを作成したら、そのインデックス名を指定してCLUSTERコマンドを実行し、テーブルデータの物理的な順序を実現できます。

テーブルがクラスター化されると、インデックス情報に基づいて物理的に並べ替えられます。クラスタリングは1回限りの操作です。その後テーブルが更新されても、変更はクラスター化されません。つまり、インデックスの順序に従って新しい行または更新された行を保存しようとしません。

クラスターの構文:

最初に、インデックス名を使用してCLUSTERを実行する必要があります。

CLUSTER table_name USING index_name;

テーブルをクラスター化します:

CLUSTERをIndexで実行したら、次にCLUSTER TABLEのみを実行する必要があります。これは、どのインデックスがすでにCLUSTERとして定義されているかを知っているからです。

CLUSTER table_name;
11
Anvesh

クラスターのインデックス作成

クラスタインデックスとは、ディスク上で互いに近い値を実際に格納するようにデータベースに指示することを意味します。 SQLテーブルの行を一意に識別できます。すべてのテーブルには、クラスター化インデックスを1つだけ持つことができます。クラスターインデックスは、複数の列をカバーできます。既定では、プライマリキーを持つ列には既にクラスター化インデックスがあります。

辞書

辞書自体は、クラスター化インデックス付きのテーブルです。すべてのデータがアルファベット順に物理的に保存されているためです。


非クラスターインデックス

非クラスター化インデックスは、本の単純なインデックス付けのようなものです。これらは、データの高速検索にのみ使用されます。一意のデータがあるかどうかはわかりません。非クラスター化インデックスには非クラスター化インデックスキーが含まれ、各キーにはデータの場所のポインターが含まれます。書籍のコンテンツインデックスには、トピックまたは章のキーとそのページの場所が含まれています。

書籍のコンテンツインデックス

書籍のコンテンツテーブルは、コンテンツ名とそのページの場所を覚えているだけです。データが一意であるかどうかはわかりません。同じ段落またはテキスト行またはWordを何度も配置できるためです。


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
);
"profile_pkey" PRIMARY KEY, btree (uid)
"profile_phone_key" UNIQUE CONSTRAINT, btree (phone)
"profile_username_key" UNIQUE CONSTRAINT, btree (username)
CREATE INDEX profile_index ON profile(uid, username);

これは実際には非クラスターインデックスです。クラスターインデックスになりました

ALTER TABLE profile CLUSTER ON profile_index;

テーブル\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)

参照してください、profile_index CLUSTER

CLUSTER profile;
1
Rafiul Islam

SQLを使用して特定のテーブルがCLUSTERedであるかどうかを知りたい場合は、次のクエリを使用して、使用されているインデックスを表示できます(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;
1
seb