本篇中记录下数据库索引相关的知识点!

索引是什么?
举个例子;大家去图书馆借书时,会先在电脑检索书名或作者等关键字信息,查询出该本书对应的一个图书索引后,紧接着就可以拿着这个图书索引去精确定位存放该索引范围内的书架并找到这本书!
所以数据库索引也是这个作用,通过在表的一列或多个列上建立索引对象,用于加快数据的检索。但索引也有缺点,过多的索引会占用硬盘空间以及导致insert、update、delete语句的执行效率降低!

(一)索引的类型

  1. 普通索引和唯一索引:
    普通索引: MySQL中最基础的索引类型,允许在定义索引的列中插入重复值和空值。
    唯一索引:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值和组合必须唯一。
    主键索引是一种特殊唯一索引,不行允许有空值。
  2. 单列索引和组合索引:
    单列索引:一个索引只包含一个列,一个表也可以有多个单列索引。
    组合索引:在表的多个字段组合上创建的索引,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用。使用组合索引时遵循最左前缀集合。
  3. 全文索引:
    全文索引类型为FULLTEXT,在定义索引的列上支持全文查找,允许在这些索引列中插入重复值和空值。全文索引可以在CHAR,VARCHAR或者TEXT类型上创建。只有MyISAM存储引擎支持全文索引。
  4. 空间索引:
    空间索引是对空间数据类型的字段建立索引,Mysql中的空间数据有4中:GEOMETRY、POINT、LINESTRING和POLYGON。Mysl使用SPATIAL关键字进行扩展,使得能够创建正规索引类似的语法创建空间索引。创建空间索引的列,必须将其声明为NOT
    NULL,空间索引只能在存储引擎为MyISAM中创建。

(二)索引的命名规范

一般来说,每家公司可能存在自己的一套规范;也可参照以下的比较通用的索引命名规则(通过索引类型简写前缀 + 下划线_ + 字段名(组合索引多个字段则继续加_)拼接而成,名称需使用小写字母,同时避免用到MySQL保留关键字):

  • 唯一索引:使用uni_[字段名]来命名,比如用户名唯一索引uni_username
  • 非唯一索引:使用idx_[字段名]来命名,比如用户名普通索引idx_username,用户名手机号组合索引idx_username_phone

索引的最佳规则:Primary key > Unique key > 一般索引

(三)索引的建立原则

  • 定义有主键和外键的字段列一定要建立索引(数据库默认建立主键索引);
  • 对于查询频率高,频繁作为 WHERE 条件且不同值较多的列,以及频繁出现在关键字ORDER BY、GROUP BY、DISTINCT后面的列,需要建立索引;
  • 经常与其他表进行JOIN连接的表,在连接字段上应该建立索引;
  • 对于那些查询中很少涉及的列,重复值比较多的列(一般为逻辑型字段,比如性别,只有男、女、其他三种值,这种字段区分度不高)不要建立索引;
  • 频繁更新的字段不适合建立索引;
  • 索引应该建在小字段上,对于定义为text等文本数据类型的列不要建立索引;
  • 表的数据量很少的情况下不适合建立索引;
  • 限制每张表上的索引数量,不超过5个;

(四)索引失效的情况

下面列举一些索引失效的情况(MySQL8.0版本,根据explain分析执行计划中的key信息是否用到索引):

1. where条件中使用OR

分以下三种情况(user表的索引有主键索引和唯一索引uni_phone):

  • OR连接的字段若有非索引字段,则索引失效:
  • OR连接的字段若是两个不同的索引字段或者同一个组合索引的不同字段,则索引失效(可以用UNION代替OR):
  • OR连接的字段若是两个相同的索引字段,则索引生效(可以用IN代替OR):
2. where条件中使用LIKE

分以下两种情况(user表的索引有主键索引和唯一索引uni_phone):

  • LIKE的值中带%或者_的前缀匹配符,则索引失效:
  • LIKE的值中带%或者_的通配符,但不置于其前缀,则索引生效:
3. where条件中使用了 组合索引,但没有遵循最左前缀原则

组合索引的最左前缀原则:假如在只建立了一个组合索引(a,b,c)的情况下,那么实际上相当于建立了(a), (a,b), (a,b,c)共三个索引。
但根据最左前缀原则,在使用索引时,只有where a = 'test1'where a = 'test1' AND b = 'test2where a = 'test1' AND c = 'test3以及where a = 'test1' AND b = 'test2 AND c = 'test3'会索引生效(条件中的字段顺序可以打乱,但字段必须得满足);
而类似于where b = 'test2'where c = 'test3'以及where b = 'test2 AND c = 'test3'则索引失效;

例子(user表的索引有主键索引和组合索引idx_username_email_phone):
索引失效的情况:

索引生效的情况:

4. where条件中对索引列使用函数

user表的索引有主键索引和唯一索引uni_username,在查询中对索引字段username使用了函数,因此这种情况下索引失效:

5. where条件中对索引列使用数学运算

比如对主键索引执id执行id/2,则会出现索引失效:
所以在实际中我们应该改成id = a/2,这时就会索引生效:

6. where条件中存在对索引列的数据类型隐式转换

user表的索引有主键索引和唯一索引uni_phone,且phone字段类型为varchar类,但在查询条件中没有加引号,所以存在隐式转换,因此这种情况下索引失效:

7. where条件中存在NOT EXISTS

使用到NOT EXISTS语法会索引失效(user表的索引有主键索引):

8.where条件中存在NULL

存在IS NULL或者IS NOT NULL的null值判断,分两种情况(user表的索引有主键索引和唯一索引uni_username):

  • 当查询的数据不仅只有索引字段列时,则索引失效:

  • 当查询的数据只有索引字段列时,则索引生效(实际中基本不会这么用):

注意:以上是MySQL8.0版本的索引失效情况,但在MySQL5.7版本中,除了以上这些情况外,还包括下面的情况会索引失效:

  1. MySQL5.7,表关联时,关联字段字符集不一致会导致索引失效
  2. MySQL5.7,使用 != 或 IN 或 NOT IN 且返回值不只有索引列

顺带说下MySQL如何查索引以及参数信息的含义
查索引语句:

 SHOW INDEX FROM database[数据库名,可省略].tableName[表名]

返回参数对应的含义:

参数 解释说明
Table 表示索引对应的数据表名
Non_unique 表示该索引是否是唯一索引。若不是唯一索引,则该列的值为 1;若是唯一索引,则该列的值为 0。
Key_name 表示索引的名称,id主键索引默认是PRIMARY。
Seq_in_index 表示该列在索引中的位置,如果索引是单列的,则该列的值为 1;如果索引是组合索引,则该列的值为每列在索引定义中的顺序。
Column_name 表示定义索引的列字段。
Collation 表示列以何种顺序存储在索引中。在 MySQL 中,升序显示值“A”(升序),若显示为 NULL,则表示无分类。
Cardinality 索引中唯一值数目的估计值。基数根据被存储为整数的统计数据计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL 使用该索引的机会就越大。
Sub_part 表示列中被编入索引的字符的数量。若列只是部分被编入索引,则该列的值为被编入索引的字符的数目;若整列被编入索引,则该列的值为 NULL。
Packed 指示关键字如何被压缩。若没有被压缩,值为 NULL。
Null 用于显示索引列中是否包含 NULL。若列含有 NULL,该列的值为 YES。若没有,则该列的值为空。
Index_type 显示索引使用的类型和方法(BTREE、FULLTEXT、HASH、RTREE),创建索引时不指定则默认是BTREE。
Comment 显示评注。

至此,我们就可以根据慢sql去创建相对应的索引对数据库查询进行优化啦!

MySQL数据库索引的类型、命名规范、建立原则以及索引失效的情况相关推荐

  1. mysql java datetime_Java向mysql数据库插入datetime类型数据实例(精)

    在Mysql数据库中日期跟时间有两种: 1.date类型,date类型也就是我们常见的储存yyyy-MM-dd类型的日期,它不能储存时间,也就是只能储存日期, 2.dateitme就是可以储存日期同时 ...

  2. linux下查看mysql数据库的字段类型_系统运维|[小白技巧]如何在Linux上检查MySQL数据表的存储引擎类型...

    提问: 我想要知道我的MySQL数据库是MyISAM还是Innodb类型.我该如何检查MySQL数据库表的类型? MySQl主要使用两种存储引擎:MyISAM 和 Innodb.MyISAM是非事务的 ...

  3. MySQL 数据库的字符串类型

    字符串类型 MySQL 数据库的字符串类型有 CHAR.VARCHAR.BINARY.BLOB.TEXT.ENUM.SET.不同的类型在业务设计.数据库性能方面的表现完全不同,其中最常使用的是 CHA ...

  4. MySQL数据库中有字段类型是日期,时间的插入语句处理

    MySQL数据库中有字段类型是日期,时间的插入语句处理 什么是时间戳? TIMESTAMP是一种类型,具体的值:19990717080000 CURRENT_TIMESTAMP是什么意思? on up ...

  5. Oracle与MySQL数据库大型对象类型(TinyBlob Blob Mediumblob LongBlob / BLOB CLOB NCLOB BFILE )的区别

    MySQL数据库中BLOB类型分为以下四种 TINYBLOB可变长二进制数据,最多255个字节 BLOB可变长二进制数据,最多2的16次方-1个字节 即64K MEDIUMBLOB可变长二进制数据,最 ...

  6. Mysql数据库的字段类型:

    数据库的数据类型和字段属性: 1.数值 ①tinyint     十分小的数据          1个字节 ②smallint    较小的数据            2个字节 ③mediumint ...

  7. mysql中对一个表的id建立了唯一索引,那么查询的select count(*) ,select count(1) ,select count(id),select count(列名)

    1.mysql中对一个表的id建立了唯一索引,那么查询的select count(*) ,select count(1) ,select count(id),select count(列名) 的查询结 ...

  8. mysql 字段名称规范_数据库表及字段命名规范

    数据库设计表及字段命名规范(我整理的,望大家多多提建议) 1.数据库表命名规范: (1)表名前应该加上前缀,表的前缀一个用系统或模块的英文名称缩写,前缀全部大写或首字母大写,表名中包含的单词首字母大写 ...

  9. Mysql存储过程名规则_数据库对象命名规范一(原则、命名、 表、视图、存储过程、函数、触发器命名规范)...

    命名规范是指数据库对象如数据库(SCHEMA).表(TABLE).索引(INDEX).约束(CONSTRAINTS)等的命名约定. 1. 原则命名使用具有意义的英文词汇,词汇中间以下划线分隔. 命名只 ...

最新文章

  1. js 多维数组长度_C++申请与释放动态数组1(学习笔记:第6章 16)
  2. 推荐100份:高并发高可用和中台一网打尽
  3. IDEA如何将git分支代码合并到master
  4. 替换某个目录下的文本文件内容字符串
  5. CUDA学习笔记之程序优化
  6. Redis数据持久化之AOF持久化
  7. logstash使用中遇到的问题
  8. opencv中Mat与IplImage,CVMat类型之间转换
  9. linux远程桌面MacOS,如何在Linux或macOS中使用远程桌面连接到Windows 10 | MOS86
  10. 动态取值_软件测试|动态测试技术
  11. HoloLens 2开发:电脑端PC识别Vuforia
  12. mysql 怎么改属性_mysql怎么修改字段的属性
  13. PostFix postqueue 指令
  14. 最新BXP2006无盘教学办公系统
  15. 基于51单片机的手机电话拨号盘模拟protues仿真
  16. 【python】详解pandas库的pd.merge_ordered与pd.merge_asof
  17. mac改变ipv4地址无法上网
  18. 【Java】如何优雅的使用HttpClient
  19. JMeter-接口自动化测试读取用例,执行并结果回写
  20. 知乎大佬图文并茂的epoll讲解,看不懂的去砍他

热门文章

  1. IntelliJ IDEA 2019.1.3 - Cannot import to svn: No appropriate protocol (protocol is disabled or ciph
  2. MySQL 日期类型及默认设置
  3. 用html和css语言编写一个登录页面,简单css登录页面
  4. python编程实战案例--turtle图案绘制
  5. 刚刚开始学习java,自己慢慢写了最基础的吃货联盟
  6. Scala to和until的区别
  7. PHP代码审计(全)
  8. java solid设计原则_设计模式之SOLID原则
  9. opencv高斯金字塔
  10. Elastic Certified Engineer复习记录-复习题详解篇-索引数据(3)