Postgresql

bigints 上的複合索引

  • October 14, 2019

我有一個使用者關係表,它基本上儲存了使用者的所有單向關係。例如,使用者A關注使用者B;使用者 X阻止使用者 Y

使用者 ID:

使用者的 id 是bigints。這不像我認為使用整數真的會遇到瓶頸(除非我的應用程序增長到超過 20 億使用者,那就是:)),但據我了解,如果我整合社交網路註冊,Facebook 使用 bigints對於他們的使用者 ID,因此我必須將使用者的 ID 保持為 bigint。

索引

起初我想為兩個使用者(相關和相關)創建一個複合索引,但是由於兩個索引都是 bigint,意味著每個 8 個字節,儲存這樣一個怪異的索引不是浪費嗎?我最終只留下了一個列索引,但不確定在這種情況下這是否是最明智的決定。

我還想到了一個帶有覆蓋索引的變體 - 但在這種情況下,relation_type(follow, block) 不會成為索引/過濾的一部分,所以也許我應該將它包含在復合索引中,但是我會有 8+8+ 4字節的索引。在這種情況下,我不清楚空間和時間之間的權衡。對此事有任何想法將不勝感激。

第一個變體(單列索引):

CREATE TABLE user_relations (
   relating_user_id bigint NOT NULL,
   related_user_id bigint NOT NULL,
   relation_type smallint NOT NULL,
   created_at default current_timestamp,

   PRIMARY KEY (relating_user_id),
   FOREIGN KEY (relation_type) references user_relations_types (id)

   -- will having only one index affect the performance really ? 
   -- should I include the type into the composite type ?
);

第二種變體(使用覆蓋索引並省略 PK):

   CREATE TABLE user_relations (
       relating_user_id bigint NOT NULL,
       related_user_id bigint NOT NULL,
       relation_type smallint NOT NULL,
       created_at default current_timestamp,

       FOREIGN KEY (relation_type) references user_relations_types (id),
       CREATE UNIQUE INDEX relating_user_related_user_relation_type_idx ON user_relations 
                   (relating_user_id, related_user_id) INCLUDE (relation_type);

       -- should I include the type into the composite type ?
   );

索引使用空間,16 字節的密鑰無需擔心。

user_relations所以你應該在 on上定義主鍵(relating_user_id, related_user_id)。如果您需要按 搜尋 relation_type,將列放入列表將無濟於事INCLUDE,因為此類列不能用作索引掃描的過濾器。

我看到兩個選項:

  1. 除了上面建議的主鍵之外,在(relating_user_id, relation_type)和上有額外的索引(related_user_id, relation_type)
  2. 如果您想擁有更少的索引,請定義主鍵(relating_user_id, relation_type, related_user_id)並僅定義一個附加索引。如果數據庫允許同一使用者之間存在幾種不同的關係,也許您可以接受它。

要定義哪些索引的決定因素應該是您必須經常有效地服務的查詢。設計這些查詢,問題會變得更容易。

引用自:https://dba.stackexchange.com/questions/250970