在 MySQL 5.5 中拥有类似 PostgreSQL 的部分索引

Léo*_* 준영 10 mysql index

我有大数据,我一次只选择一小段数据,这样选择总是按顺序排列的。我正在尝试在 MySQL 中实现像 Partial index 这样的 PostgreSQL,这是针对此类目的。我不确定部分唯一约束是否与我想要的相同。

PostgreSQL 9.4 中的代码

CREATE UNIQUE INDEX dir_events
    ON events (measurement_id)
    USING btree
    (eventBody)
    WHERE is_active;
Run Code Online (Sandbox Code Playgroud)

尝试在 MySQL 中对 ypercube 的部分索引

CREATE UNIQUE INDEX dir_events
    [index_type] -- TODO what here?
    ON events (measurement_id, is_active)
    [index_type] -- TODO what here?
Run Code Online (Sandbox Code Playgroud)

如何在 MySQL 5.5 或类似版本中创建类似 PostgreSQL 的部分索引?

ype*_*eᵀᴹ 13

MySQL 和兄弟姐妹(MariaDB、Drizzle 等)都没有实现部分索引。

考虑到此限制,您可以做什么:

  • a) 在 上做一个简单的(不是部分的)索引(is_active, measurement_id)。它将用于部分索引所在的查询中。当然,如果is_active列是 3% 的真和 97% 的假,这个索引就会大得多(比部分索引大得多)。但仍然比表小,对这些查询很有用。
    另一个限制是索引不能UNIQUE与此解决方案一起使用,因此不强制执行约束。如果索引是用 来创建的UNIQUE,那么也会对行强制执行唯一性is_active = FALSE。我假设你不想要这样:

    CREATE INDEX dir_events
        ON events (is_active, measurement_id)
        USING btree ;
    
    Run Code Online (Sandbox Code Playgroud)
  • b1)(b 的简单变体):在您的设计中添加另一个表,其中只有 的主键列events和 的外键events。该表应该只有is_active原始表中为 true 的行(这将由您的应用程序/过程强制执行)。查询is_active = TRUE将更改为连接到该表(而不是WHERE条件)
    UNIQUE此解决方案也未强制执行此操作,但查询只会执行简单的连接(连接到更小的索引)并且应该非常有效:

    CREATE TABLE events_active
    ( event_id INT NOT NULL,         -- assuming an INT primary key on events
      PRIMARY KEY (event_id),
      FOREIGN KEY (event_id)
        REFERENCES events (event_id)
    ) ;
    
    INSERT INTO events_active 
      (event_id)
    SELECT event_id
    FROM events
    WHERE is_active = TRUE ;
    
    Run Code Online (Sandbox Code Playgroud)
  • b2) 一个更复杂的解决方案:在你的设计中添加另一个表,只有表的主键列measurement_id. 与之前的建议一样,该表应该只有is_active原始表中为 true 的行(这也将由您的应用程序/过程强制执行)。然后仅将此表用于具有WHERE is_active = TRUE且仅需要该measurement_id列的查询。如果从需要更多的列events,你必须join像以前一样。
    UNIQUE约束可以使用此解决方案来执行。measurement_id列的重复也可以保证一致(具有额外的唯一约束events和复合外键):

    ALTER TABLE events
      ADD UNIQUE (event_id, measurement_id) ;
    
    CREATE TABLE events_active
    ( event_id INT NOT NULL,
      measurement_id INT NOT NULL.
      PRIMARY KEY (event_id, measurement_id),
      UNIQUE (measurement_id),
      FOREIGN KEY (event_id, measurement_id)
        REFERENCES events (event_id, measurement_id)
    ) ;
    
    INSERT INTO events_active 
      (event_id, measurement_id)
    SELECT event_id, measurement_id
    FROM events
    WHERE is_active = TRUE ;
    
    Run Code Online (Sandbox Code Playgroud)
  • c) 也许是最简单的:使用 PostgreSQL。我确定有适用于您的 Linux 发行版的软件包。它们可能不是 Postgres 的最新版本,但部分索引是在 7.0(或更早?)中添加的,因此您应该没有问题。另外,我相信您几乎可以在任何 Linux 发行版中安装最新版本 - 即使有点麻烦。您只需要安装一次。