MySQL 中未使用的索引:基本指南

2021-09-17 11:07:31 浏览数 (2815)

在 MySQL 中,未使用的索引会浪费空间并使查询变慢。本篇文章将向大家展示如何识别未使用的索引并避免创建它们。

介绍

正确设计和使用在多种 MySQL 中可用的索引可能是一个挑战,因为它们的类型多种多样,并且它们具有独特的所有细微差别。但是,不要担心——这篇文章为想要了解 MySQL 如何在更深层次上使用索引的人是一个不错的起点。

什么是索引,我们应该在什么时候使用它们?

在最基本的形式中,数据库索引充当记录列表——这些记录引用了它们所在的数据库结构。索引主要用于消除数据的考虑,并通过这样做使查询更快。如果没有索引,数据库必须一次一行地读取表中存在的所有数据,这意味着如果我们的表有 100,000 条记录,则数据库必须通读其中的大部分,直到找到适合我们的行. 然而,使用索引,数据库可以排除某些行,扫描更少的行,并更快地返回结果。

索引有多种类型——每一种都适用于不同的事物;例如,如果我们的主要查询使用相等运算符 (=)、大于 (>)、大于或等于 (>=)、小于 (<)、小于或等于,B 树索引可能很适合我们(<=) 运算符或​BETWEEN​关键字,以及在某些特定情况下的​LIKE​查询。 

当存储在我们列中的数据非常大时,前缀索引可能很有用,因此,索引整个列可能是不可能的等等。由于我们已经涵盖了 MySQL 中索引的一些微妙之处,因此我们不会在这篇博文中没有详细介绍,但了解以下内容应该会有所帮助:

设想

索引对我们有帮助吗?

我们的应用程序主要运行 SELECT 查询。是的
我们经常在数据库中更新、删除或插入数据,而无需执行许多读取操作。
我们正在处理大数据集并希望搜索数据(例如,我们希望构建一个搜索引擎,允许我们搜索大量数据。)是的
我们正在处理大数据集,我们的应用程序在不使用搜索功能的情况下充当信息存档。

在上面,你可以看到开发人员可以使用索引的一些最基本和最常见的场景。关于索引的一般思想是索引加快SELECT查询速度,同时减慢所有其他类型的查询速度——它们减慢其他类型的索引速度,因为数据库需要做一些额外的工作——例如,当向表中插入数据时,数据库必须向某个表的每个索引添加一条新记录。将其乘以你拥有的索引数量,你就已经看到某些类型查询的性能下降的速度有多快。

现在我们已经了解了一些基础知识,让我们进入正题——我们可以做些什么来使我们的索引对 MySQL 真正必要?

确保 MySQL 使用索引

如果我们想确保我们的 MySQL 实例使用我们提供给它们的索引,我们有几个选择:

选项

信息
手动方法涉及通过phpMyAdmin或其他管理工具手动检查表结构、索引信息等。
使用EXPLAINMySQL 提供的查询EXPLAIN查询将为我们提供相关信息,帮助我们确定我们的查询是否使用索引。我们需要考虑的possible_keyskeykey_length列。该possible_keys列将显示 MySQL 能够从中选择的所有可能的索引,该key列将显示实际选择的索引,而该key_length列将显示 MySQL 选择的索引的长度。

要创建对你的 MySQL 实例有用的索引,你需要注意的一件事是你将要使用的索引类型——但是,你还需要注意要使用多少个索引使用和缓慢性能之间创造一个权衡​INSERT​,​UPDATE​以及​DELETE​查询和更快的性能​SELECTs​表示会接受你。为此,首先,向你的 MySQL 实例添加一个索引——Arctype,导航到要向左侧添加索引的表,然后单击“编辑表”:如果你想为其添加唯一索引,例如,单击约束下方的按钮并对其进行编辑(在这种情况下,选中“唯一”应该可以解决问题):

为 MySQL 实例创建索引,

完成后,单击应用,你的更改应该会在你的数据库实例上可见:

MySQL 实例的索引,

一旦您的更改生效,Arctype 也会通知你 :

数据库实例

将相关索引添加到数据库后,就可以EXPLAIN发挥它的魔力了。连接到您的数据库实例,然后EXPLAIN在你的查询前面添加以查看它的作用以及你的查询是否使用您定义的索引:

EXPLAIN SELECT * FROM arctype WHERE demo_column = 'Demo Data';
+----+-------------+---------+------------+-------+---------------+-------------+---------+-------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+---------------+-------------+---------+-------+------+----------+-------------+
| 1 | SIMPLE | arctype | NULL | const | demo_column | demo_column | 602 | const | 1 | 100.00 | Using index |
+----+-------------+---------+------------+-------+---------------+-------------+---------+-------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)

为了最大限度地使您的列对 MySQL 有用,您需要完成以下步骤:

  1. 仅查询您已编入索引的列 - 这样做将吸引最大的成功机会。换句话说,确保您要查询的列是隔离的 - 将WHERE子句之后的所有内容单独保留,不要将任何内容混入其中,同时避免将索引列作为查询中的表达式或函数的一部分。例如,避免发出诸如​SELECT * FROM demo_table WHERE column_1 = ‘Demo’ AND column_2 = ‘Demo 2’;ifcolumn_2​未编入索引且仅编入索引column_1等查询。
  2. 查找列中的 " Using index" 值Extra——这是 MySQL 告诉我们是否正在使用索引。
  3. 如果你想看看一切此外,一定要探索possible_keys,key和key_len列,以及:在possible_keys列描绘了索引的MySQL可以从选择中,key列涵盖实际上选择的指数和key_len描绘了索引的长度。由于你不再担心用于运行查询的 SQL 客户端(你已经在使用 Arctype,不是吗?),这并不是很复杂。

索引角落案例

总的来说,到现在为止,你可能已经明白,要使索引成为必需,你应该非常谨慎地选择它们的类型,并且在可能的情况下,使用EXPLAIN 查询,这意味着上述建议应该使你的数据库和索引走上良好的道路。然而,很大一部分索引变得过时和不必要是因为 MySQL 不是很挑剔;它通常会接受我们扔给它的任何东西。索引也是如此——如果你有 10 行并决定将它们全部建立索引,你可以这么做,而且 MySQL 肯定能够完成你的请求,但有什么意义呢?在这种情况下,添加索引会浪费磁盘空间。

你应该避免总是求助于索引来提高性能——分区和其他功能也可以做一些很棒的工作。如果这不能解决你的所有问题,请考虑规范化你的数据库模式——这将使你更接近完美的数据库。如果这也不能让您走得很远,请考虑探索 MySQL 和 MariaDB 的文档:这应该可以解决问题。