第 31.1 节:创建索引

为表 my_table 中的列 name 创建索引:

CREATE INDEX idx_name ON my_table(name);

第 31.2 节:创建唯一索引

唯一索引可防止在表中插入重复数据。可以在组成唯一索引的列中插入 NULL 值(因为 NULL 值与任何其他值都不同,包括另一个 NULL 值)。

为表 my_table 中的列 name 创建唯一索引:

CREATE UNIQUE INDEX idx_name ON my_table(name);

第 31.3 节:AUTO_INCREMENT 键

CREATE TABLE (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY(id),
    ...
);

主要注意事项:

  • 从 1 开始,当你在 INSERT 时未指定该列或将其指定为 NULL 时,会自动递增 1。
  • ID 之间始终是不同的,但……
  • 不要对 ID 的值做任何假设(无间隙、连续生成、不被重用等),除了在任意时刻它们是唯一的。

细微注意事项:

  • 重启服务器时,“下一个”值会计算为 MAX(id) + 1。如果关闭或崩溃前的最后一个操作是删除了最大的 ID,那么该 ID 可能会被重用(这取决于存储引擎)。因此,不要相信 auto_increment 是永久唯一的;它们只是在任意时刻唯一。
  • 对于多主或集群解决方案,请参阅 auto_increment_offset 和 auto_increment_increment。
  • 可以使用其他列作为 PRIMARY KEY 而仅对 id 列建立 INDEX(id)(在某些情况下是一种优化)。
  • 使用 AUTO_INCREMENT 作为“分区键”很少有益处;请用其他方式。
  • 各种操作可能会“消耗”值。当它们预先分配值但最终未使用时会发生这种情况:INSERT IGNORE(重复键时)、REPLACE(即 DELETE 加 INSERT)等。ROLLBACK 也是导致 ID 出现间隙的原因之一。
  • 在复制中,不能相信 ID 会按升序到达从库。虽然 ID 是按顺序分配的,但 InnoDB 语句是按 COMMIT 顺序发送到从库的。

第 31.4 节:创建复合索引

这将创建两个键 mystring 和 mydatetime 的复合索引,并加速在 WHERE 子句中同时包含这两个列的查询。

CREATE INDEX idx_composite ON mytable (mystring, mydatetime);

注意:顺序很重要! 如果搜索查询的 WHERE 子句没有同时包含这两列,它只能使用最左边的索引。在这种情况下,WHERE 中包含 mycol 的查询将使用该索引,而搜索 myothercol 而不同时搜索 mycol 的查询则不会使用该索引。更多信息请查看相关博客文章。

另外,由于 B 树的工作原理,通常按范围查询的列应放在复合索引的最右边。例如,DATETIME 列通常按 WHERE datecol > '2016-01-01 00:00:00' 查询。B 树索引能非常高效地处理范围查询,但仅当作为范围查询的列是复合索引的最后一列时。

第 31.5 节:删除索引

删除表 my_table 中列 name 的索引:

DROP INDEX idx_name ON my_table;