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 而不是所有员工的数据。

指数

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

独特的

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

如何创建索引

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

创建 PRIMARY KEY 索引

创建 PRIMARY KEY 索引的最简单方法是在创建表时进行。 我们将在本教程中使用一个员工表示例。 该表将包含三列: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 创建索引

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

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

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

CREATE INDEX idx1 ON EMPLOYEE (LASTNAME);

现在在此表上按 LASTNAME 进行搜索会更快。 在本例中,“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);

创建唯一索引

有时您可能希望在列上创建索引并强制该列中的所有条目都是唯一的。 如果我们扩展我们的示例表以包含一个 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);

您会在第二次插入时收到错误:

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,或打开一个 聊天 或与我们联系,与我们知识渊博的解决方案或经验丰富的托管顾问之一交谈,以了解您今天如何利用这项技术!