MySQL对相同字段创建不同索引解析

 更新时间:2023年11月22日 10:37:03   作者:爱可生开源社区  
这篇文章主要为大家介绍了MySQL 对相同字段创建不同索引解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

MySQL 可以对相同字段创建不同索引?

Oracle 不允许同一个字段存在两个相同索引,但这个和 MySQL 的设计不太相同,通过实验,了解一下 MySQL 这种场景的情况。

同事问了个问题,MySQL 的某个测试库,发现有这种情况:

  • 给已设置为主键的列又加了一次索引,如下前两条 SQL 语句。
  • 给同一个字段加了 2 次索引,如下后两条 SQL 语句。
# 情况 1
ALTER TABLE test ADD PRIMARY KEY USING BTREE(ID);
ALTER TABLE test ADD INDEX idx_test01 USING BTREE(ID);
# 情况 2
ALTER TABLE test ADD INDEX idx_test02 USING BTREE(UPDATED):
ALTER TABLE test ADD INDEX idx_test03 USING BTREE(UPDATED);

正常情况只需要一条 SQL 就行?

这种情况是不是没有意义?

这两个问题考察的都是关于索引的基础知识,如果对此很熟悉,答案不言自明,即使不熟悉,只需要做些简单的测试,就可以了解,加深印象。

测试一

数据库版本:MySQL 8.0,为表 t 设置主键,再对同字段加个索引可以执行成功。

alter table t add primary key using btree(id);
alter table t add index idx_t_id using btree(id);

对字段 c1 创建两个索引,都可以执行成功。

alter table tbl add index idx_t_001 using btree(c1);
alter table tbl add index idx_t_002 using btree(c1);

以上实验说明:MySQL 中可以对相同的字段创建多次相同的索引。

测试二

通过 explain,可以验证出对于同时存在 PRIMARY KEY 和普通索引的字段作为检索条件时,优化器会选择 PRIMARY KEY 作为 key,这种选择应该和 MySQL 以索引组织表存储的形式有关,对于同时存在两个索引名称的相同字段作为检索条件时,优化器会选择先创建的索引作为 key,这倒是很像 Oracle 中 RBO 对于索引选择的顺序判断逻辑(可能有些不严谨,但是因为完全是两个相同的索引(Oracle 终不会允许此种情况),cost 应该完全一致,所以选择谁,好像无所谓)。

bisal@mysqldb 13:02:  [test]> explain select * from tbl where id=1;
+----+-------------+-------+------------+-------+------------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type  | possible_keys    | key     | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+-------+------------------+---------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | tbl   | NULL       | const | PRIMARY,idx_t_id | PRIMARY | 4       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+-------+------------------+---------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.07 sec)

bisal@mysqldb 13:03:  [test]> explain select * from tbl where c1='a';
+----+-------------+-------+------------+------+---------------------+-----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys       | key       | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------------+-----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | tbl   | NULL       | ref  | idx_t_001,idx_t_002 | idx_t_001 | 7       | const |    3 |   100.00 | NULL  |
+----+-------------+-------+------------+------+---------------------+-----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

以上实验说明 MySQL 对于相同字段的相同索引选择方面的逻辑。

测试三

从效果上看,这两个索引,保留一个即可,因为这两个索引只是名称不同,索引字段相同的,实际上就是相同的索引。

ALTER TABLE test ADD INDEX idx_test02 USING BTREE(UPDATED):
ALTER TABLE test ADD INDEX idx_test03 USING BTREE(UPDATED);

但对于主键和索引的这两个,需要用主键这个。因为这两个最主要的区别就是主键除了包含索引外,还需保证唯一,而此处的索引,就是普通索引,不是唯一索引,因此从逻辑上,这两个是不等价。但是由于主键包含了索引,因此可以删除第二个索引,它属于重复的,主键的定义包含了索引的定义。

ALTER TABLE test ADD PRIMARY KEY USING BTREE(ID);
ALTER TABLE test ADD INDEX idx_test01 USING BTREE(ID);

MySQL 之所以存在上面的这些问题,因为它允许创建不同名称相同索引字段的索引,但是如果是 Oracle,情况会是相同?

Oracle 19c,在主键字段上创建索引,会提示 此列列表已索引 的错误。在相同字段上创建第二个索引,也是提示 此列列表已索引 的错误。说明 Oracle 中根本不允许同一个字段存在两个相同索引的情况。

总结

因此只能说不同的数据库,设计理念不同,Oracle 更严谨些,MySQL 的容错性鲁棒性更突出(可能不太准确)。使用的时候,需要对这些基础能够有所了解,才可以针对合适的场景选择合适的操作。

以上就是MySQL 对相同字段创建不同索引解析的详细内容,更多关于MySQL字段创建索引的资料请关注脚本之家其它相关文章!

相关文章

  • mysql千万级数据分页查询性能优化

    mysql千万级数据分页查询性能优化

    本文给大家分享的是作者在使用mysql进行千万级数据量分页查询的时候进行性能优化的方法,非常不错的一篇文章,对我们学习mysql性能优化非常有帮助
    2017-11-11
  • mysql8报错:ERROR 1410 (42000): You are not allowed to create a user with GRANT解决办法

    mysql8报错:ERROR 1410 (42000): You are not allowed to 

    电脑新装的mysql,版本为8.0以上,分配权限时直接带密码和账号会报错,这篇文章主要给大家介绍了关于mysql8报错:ERROR 1410 (42000): You are not allowed to create a user with GRANT的解决办法,需要的朋友可以参考下
    2022-06-06
  • 阿里云ECS云服务器(linux系统)安装mysql后远程连接不了(踩坑)

    阿里云ECS云服务器(linux系统)安装mysql后远程连接不了(踩坑)

    这篇文章主要介绍了阿里云ECS云服务器(linux系统)安装mysql后远程连接不了(踩坑),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-04-04
  • 使用mysql workbench自动生成ER图的实现步骤

    使用mysql workbench自动生成ER图的实现步骤

    MySQL Workbench是一款专为MySQL设计的ER/数据库建模工具,它是著名的数据库设计工具DBDesigne4的继任者,可以通过MySQL Workbench设计和创建新的数据库图示,本文给大家介绍了使用mysql workbench自动生成ER图的实现步骤,需要的朋友可以参考下
    2024-06-06
  • centos7.2离线安装mysql5.7.18.tar.gz

    centos7.2离线安装mysql5.7.18.tar.gz

    这篇文章主要为大家详细介绍了centos7.2离线安装mysql5.7.18.tar.gz,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-06-06
  • MySQL数据库中表的操作详解

    MySQL数据库中表的操作详解

    这篇文章主要为大家详细介绍了MySQL数据库中表常用的一些操作方法,文中的示例代码讲解详细, 对我们学习MySQL有一定帮助,需要的可以参考一下
    2022-08-08
  • 关于Win10下MySQL5.7.17免安装版基本配置教程(图文详解)

    关于Win10下MySQL5.7.17免安装版基本配置教程(图文详解)

    这数据库应用是一个应用系统不可或缺的部分,关系型数据库应用大同小异,这里选择MySQL作为数据库平台。下面通过本文给大家介绍关于Win10下MySQL5.7.17免安装版基本配置教程(图文详解),需要的朋友可以参考下
    2017-06-06
  • MySQL timestamp自动更新时间分享

    MySQL timestamp自动更新时间分享

    在mysql中timestamp数据类型是一个比较特殊的数据类型,他可以自动在你不使用程序更新情况下只要你更新了记录timestamp会自动更新时间
    2013-06-06
  • 数据库Sql实现截取时间段和日期实例(SQL时间截取)

    数据库Sql实现截取时间段和日期实例(SQL时间截取)

    在许多情况下你也许只想得到日期和时间的一部分,而不是完整的日期和时间,下面这篇文章主要给大家介绍了关于数据库Sql实现截取时间段和日期(SQL时间截取)的相关资料,需要的朋友可以参考下
    2023-05-05
  • 从MySQL5.7平滑升级到MySQL8.0数据库的最佳实践教程

    从MySQL5.7平滑升级到MySQL8.0数据库的最佳实践教程

    这篇文章主要给大家介绍了关于从MySQL5.7平滑升级到MySQL8.0数据库的最佳实践,升级MySQL版本需要进行一系列操作,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2024-07-07

最新评论