在已有大量数据的表上创建 MySQL 索引

Posted

技术标签:

【中文标题】在已有大量数据的表上创建 MySQL 索引【英文标题】:Create a MySQL index on already existing table with a lot of data 【发布时间】:2021-10-15 16:28:15 【问题描述】:

我有一个带有 mysql 数据库 (AWS RDS) 的 Spring Boot 服务。

有一个特定的表,其中包含大约 200 万行,对它的一些查询会使 CPU 上升到数据库实例。

我注意到 used 列上没有索引,所以我想尝试添加此索引。

问题是:

我可以在这个表上添加(没有任何问题)这个索引吗? 已经包含很多行?我正在使用 Flyway 来管理数据库 迁移。 具体列包含字符串,有没有 在这种情况下使用其他索引配置更好吗?

一些附加信息:

MySQL 版本为5.7.33;

目前,该表不包含任何其他关系;

表格很简单,报告如下:

如果不存在则创建表info(

field_1varchar(36) 非空,

field_2 文本默认为空,

my_keyvarchar(36) 默认为空,

field_3varchar(255) 默认为空,

field_4varchar(10) 默认为空,

field_4varchar(10) 默认为空,

field_6varchar(10) 默认为空,

field_7varchar(36)NOT NULL,

creation_date日期时间默认为空,

modification_date日期时间默认为空,

主键 (field_1)

) ENGINE=InnoDB 默认字符集=utf8;

该表现在包含大约 200 万 行;

查询类似于:

SELECT * FROM info WHERE my_key = "xxxx"

而且会执行很多次

想法是创建这个索引:

CREATE INDEX my_key ON info (my_key);

【问题讨论】:

您能否发布 A) 您的查询和 B) SHOW CREATE TABLE tbl_name; C) 从 tbl_name 显示索引;用于分析和 D) 您要索引的列的名称? 并向我们展示查询。它可能会从复合索引而不是单列索引(这就是您的意思)中受益更多。 桌子有多大?添加索引在最坏的情况下与表的大小成正比。什么版本的 MySQL? 我添加了请求的信息 已发布的 SHOW CREATE TABLE xxx;似乎是编造的,而不是 SHOW CREATE TABLE info 的结果;使用 VARCHAR(36) 的 PRIMARY KEY 不会长期有效,因为您创建的每个 NDX 都会在 NDX 工作中附加 PRIMARY KEY 的内容。考虑将来使用 ID 作为自动递增的数字。您使用 CREATE INDEX my_key ON info (my_key);如果您可以使用 CREATE INDEX info_ndx_my_key ON info (my_key) 之类的东西,将来会更好地为您服务;以更快地将表识别为索引名称的一部分。 【参考方案1】:

使用最新版本的 MySql,您可以create an index 而不锁定表:

在创建索引时,该表仍可用于读取和写入操作。 CREATE INDEX 语句仅在访问该表的所有事务完成后才结束,以便索引的初始状态反映该表的最新内容。

显然,创建索引对数据库来说是一项额外的工作,因此如果您的数据库处于受苦状态,请尝试在数据库上执行的活动减少时更新索引。

【讨论】:

以上是关于在已有大量数据的表上创建 MySQL 索引的主要内容,如果未能解决你的问题,请参考以下文章

Oracle表刚插入大量数据,索引会立即起作用吗?

性能优化3--数据库优化

更新 MySQL 表中的大量行

在SQL中使用 WHERE字句中使用,= < >等的表达式,是否在一个有创建索引的表上查询,索引会失效?

在基于临时会话的表上创建索引后运行统计信息

导出大量数据和内存问题