MySQL 性能:MySQL/MariaDB 索引

MySQL/MariaDB 数据库中的数据存储在表中。 考虑索引的一种简单方法是想象一个扩展的电子表格。 这种类型的系统并不总是有利于快速搜索; 这就是索引变得必不可少的地方。 如果没有索引,则数据库引擎必须从第一行开始并浏览所有行以查找相应的值。 如果这是一个小表,那没什么大不了的,但是在更大的表和应用程序中,可能存在数百万甚至数十亿行的表,它就会成为问题。 可以想象,即使在最新的硬件上,逐一搜索这些行也会很耗时。 解决方案是为您的数据创建一个索引(或多个索引)。

什么是索引?

索引是一个有组织的查找表,其中包含指向可以在数据库中检索数据的位置的指针。 这个概念类似于书籍索引。 在一本书中,索引列出了各种主题所在的页码。 在数据库中,索引以逻辑和排序顺序存储指针,从而允许在数据库中快速查找。 想象一本书没有索引。 如果您想查找有关特定主题的信息,您必须从头开始并翻阅页面,直到找到您要查找的信息。 图书索引通过准确地告诉您您正在寻找的信息是哪些页面来解决这个问题。 这基本上就是 MySQL 索引的工作方式。

MySQL什么时候使用索引?

每当数据库服务器必须查找信息时,它都会使用索引来加速该过程。 这方面的示例包括 WHERE、JOIN ON、MIN/MAX 和 ORDER BY/GROUP BY 子句。 如果您的查询要在任何这些情况下经常搜索或匹配列,则应考虑创建索引。

索引能提高数据库性能吗?

大多数时候,简短的回答是肯定的。 对于数据的读取和搜索,索引绝对可以提高性能。 不进行全表扫描将改善几乎任何 SELECT 查询。 这确实需要付出很小的代价。 对于经常被操纵的列,每次更改都会产生成本。 这会使数据库上的 INSERT 和 UPDATE 陷入困境。

常见的 MySQL 索引类型

MySQL 索引的三种常见类型:

  • 首要的关键
  • 指数
  • 独特

首要的关键

主键告诉数据库服务器哪个是表中最关键的列。 通常,这用于 auto_increment id 列。 例如,如果您有一个包含员工信息的表,您会希望在“EMPLOYEE_ID”列上有一个主键。 在其他表(即薪金表)中,您只需引用 EMPLOYEE_ID 而不是所有员工的数据。

指数

标准索引用于告诉数据库服务器表中的一个或多个列将被大量搜索,因此应该在它们上创建索引。 这可以在表创建期间构建,或者如果您以后发现需要在列上建立索引,则可以添加它。

独特

UNIQUE 索引有点不同,因为它对可以写入表的内容施加了特定的限制。 如果您尝试插入包含已包含在数据中的值的行,则 INSERT 将产生错误。 这允许快速搜索以及一些数据完整性。

如何创建索引

有多种方法可以在列上创建索引。 您可以在创建 TABLE 时或之后使用 ALTER TABLE 或 CREATE INDEX 语句设置索引。

创建主键索引

创建 PRIMARY KEY 索引的最简单方法是在创建表时进行。 我们将使用一个 example 本教程的员工表。 该表将包含三列:ID、FIRSTNAME 和 LASTNAME。 创建可能看起来像这样:

CREATE TABLE EMPLOYEE
(
  ID INT,
  FIRSTNAME CHAR(32),
  LASTNAME CHAR(32)
);

该语句将创建没有索引的表。 我们可以使用如下语句添加主键:

ALTER TABLE EMPLOYEE
  ADD CONSTRAINT PRIMARY KEY (ID);

这告诉 MySQL 我们在列 ID 上有一个主键。

一种更直接的方法是在创建表期间。 从头开始,我们将重新创建表并在一个语句中添加主键。

CREATE TABLE EMPLOYEE
(
  ID INT,
  FIRSTNAME CHAR(32),
  LASTNAME CHAR(32),
  PRIMARY KEY (ID)
);

此单个语句执行与上述前两个语句相同的任务。 一个主键可以包含多个列,但这些列必须都是唯一的。 主键可用于标识表中的任何单个行。

使用 CREATE INDEX 创建索引

使用 example 上表,假设公司有数千名员工,您希望能够通过姓氏快速搜索员工。 使用主键,只能有一个条目。 您不能有多个具有相同员工 ID 的人。 对于姓氏,多人共享同一个名字是很常见的。 同样,有几种方法可以做到这一点。 使用上表:

CREATE TABLE EMPLOYEE
(
  ID INT,
  FIRSTNAME CHAR(32),
  LASTNAME CHAR(32),
  PRIMARY KEY (ID)
);

我们可以像这样向 LASTNAME 列添加索引:

CREATE INDEX idx1 ON EMPLOYEE (LASTNAME);

通过 LASTNAME 进行的搜索现在在此表上会更快。 在这个 example,“idx1”是索引的名称。 如果我们需要,这将使将来更容易引用索引本身。

向表添加索引的另一种方法是使用 ALTER TABLE 命令。 为了完成与前面语句相同的操作,我们将运行以下命令:

ALTER TABLE EMPLOYEE ADD INDEX idx1 (LASTNAME);

添加索引以节省一些时间的最后一种方法是在 CREATE TABLE 期间执行此操作。 如果您事先知道您将要搜索或加入特定列,那么您可以创建带有索引的初始表:

CREATE TABLE EMPLOYEE
(
  ID INT,
  FIRSTNAME CHAR(32),
  LASTNAME CHAR(32),
  PRIMARY KEY (ID),
  INDEX idx1 (LASTNAME)
);

所有这三个语句都会产生相同的结果。

多列索引

索引不仅必须位于单个列上。 如果我们想要更快地查找 FIRSTNAME 和 LASTNAME,我们可以在这两列上创建索引。 在创建表中,它看起来像这样:

CREATE TABLE EMPLOYEE
(
  ID INT,
  FIRSTNAME CHAR(32),
  LASTNAME CHAR(32),
  PRIMARY KEY (ID),
  INDEX idx2 (LASTNAME,FIRSTNAME)
);

使用 CREATE INDEX 命令:

CREATE INDEX idx2 ON EMPLOYEE (LASTNAME, FIRSTNAME);

最后,ALTER TABLE 命令:

ALTER TABLE EMPLOYEE ADD INDEX idx2 (LASTNAME, FIRSTNAME);

创建唯一索引

有时您可能希望在列上创建索引并强制该列中的所有条目都是唯一的。 如果我们扩展我们的 example 表包含一个 OFFICE 列(表示他们在建筑物中拥有哪个办公室),那么我们可能希望将其设为 UNIQUE 索引。 让我们使用这张表:

CREATE TABLE EMPLOYEE
(
  ID INT,
  FIRSTNAME CHAR(32),
  LASTNAME CHAR(32),
  OFFICE INT,
  PRIMARY KEY (ID)
);

请注意,现在我们在表中存储了一个整数来表示此人在哪个办公室。 这可能是指另一个表格“办公室”,其中将包含有关建筑物中各个办公室的信息。

要为此创建索引,我们将发出以下命令:

CREATE UNIQUE INDEX idx3 ON EMPLOYEE (OFFICE);

您可以使用类似的命令在 CREATE TABLE 和 ALTER TABLE 命令中创建它们。 现在,如果您尝试运行这两个插入:

INSERT INTO EMPLOYEE (ID, FIRSTNAME, LASTNAME, OFFICE) VALUES (1, 'JANE', 'JOHNSON', 1);

INSERT INTO EMPLOYEE (ID, FIRSTNAME, LASTNAME, OFFICE) VALUES (2, 'JOHN', 'SMITH', 1);

您会在第二次 INSERT 时收到错误消息:

Duplicate entry '1' for key 'idx3'

删除索引

有时您可能不再需要列上的索引。 也许您意识到您并不经常搜索列,并且索引会减慢插入和更新速度。 为此,我们将使用 DROP INDEX 命令。 我们的表是这样创建的:

CREATE TABLE EMPLOYEE
(
  ID INT,
  FIRSTNAME CHAR,
  LASTNAME CHAR,
  PRIMARY KEY (ID),
  INDEX idx (LASTNAME,FIRSTNAME)
);

如果我们想删除 LASTNAME 和 FIRSTNAME 列上的索引,我们将发出以下命令:

DROP INDEX IDX ON EMPLOYEE;

结论

数据库索引是一种基本工具,可优化结构中的数据检索速度,该结构利用表中的搜索和读取性能。 索引增强主要以更多写入和/或存储空间为代价,以保持最佳索引数据结构。

MySQL 和 MariaDB 数据库提供了多种其他搜索和读取选项,包括此处未涵盖的许多选项。 这里的主要内容包括:

  • 确保您花时间提前计划好您的餐桌。
  • 如果您在创建表时没有提前计划,请评估搜索最多的列并为它们创建索引。

看到它在行动!

我们广泛的专用服务器产品线提供了托管最小数据库所需的功能、稳定性和安全性,以供发展中的企业到为最大型企业设置的高可用性集群服务器。 想看看我们可以提供哪些解决方案来满足您的需求?

给我们打电话 800.580.4985,或打开 聊天 或与我们联系,与我们知识渊博的解决方案或经验丰富的托管顾问交谈,了解您今天如何利用这项技术!