精心总结十三条建议,帮你创建更合适的MySQL索引

上篇文章讲到使用MySQL的Explain命令可以分析SQL性能瓶颈,优化SQL查询,以及查看是否用到了索引。

我们都知道创建索引可以提高查询效率,但是究竟如何创建索引呢?

[En]

We all know that creating an index can improve query efficiency, but how exactly do you create an index?

哪些字段适合创建索引?

哪些字段不适合创建索引?

[En]

Which fields are not suitable for index creation?

本文将帮助您了解如何创建适当的数据库索引。

[En]

This article is with you to learn how to create an appropriate database index.

1. MySQL索引的分类

在创建索引之前了解一下MySQL有哪些索引,然后我们才能选择合适的索引。

常用索引有通用索引、唯一索引、主键索引、联合索引、全文索引等。

[En]

Common indexes are general index, unique index, primary key index, joint index, full-text index and so on.

普通索引

一般指数是最基本的指数,没有任何限制。

[En]

A general index is the most basic index, without any restrictions.

您可以使用以下命令创建普通索引:

[En]

You can use the command to create a normal index:

ALTER TABLE table_name ADD INDEX index_name (column);

唯一索引

与普通索引不同,唯一索引的列值必须唯一,允许为null。

创建方式是这样的:

ALTER TABLE table_name ADD UNIQUE index_name (column);

主键索引

主键索引是一种特殊的唯一索引,并且一张表只有一个主键,不允许为null。

创建方式是这样的:

ALTER TABLE table_name ADD PRIMARY KEY (column);

联合索引

联合索引同时在多个字段上创建索引,从而提高了查询效率。

[En]

A federated index creates an index on multiple fields at the same time, which makes the query more efficient.

创建方式是这样的:

ALTER TABLE table_name ADD INDEX index_name (column1, column2, column3);

全文索引

全文索引主要用于匹配字符串文本中的关键字。

[En]

Full-text indexing is mainly used to match keywords in string text.

当需要字符串中是否包含关键字的时候,我们一般用like,如果是以%开头的时候,则无法用到索引,这时候就可以使用全文索引了。

创建方式是这样的:

ALTER TABLE table_name ADD FULLTEXT (column);

2. 哪些字段适合创建索引?

我总结了有以下几条:

2.1 频繁查询的字段适合创建索引

表中总是有热的和冷的字段,很明显,频繁使用的字段更适合对其进行索引。

[En]

There are always hot and cold fields in a table, and it’s clear that frequently used fields are more suitable for indexing it.

2.2 在where和on条件出现的字段优先创建索引

为什么不是在select后面出现的字段优先创建索引?

因为查询SQL会先匹配on和where条件的字段,具体的匹配顺序是这样的:

from > on > join > where > group by > having > select > distinct > order by > limit

2.3 区分度高的字段适合创建索引

例如,对于用户表,生日比性别更有区别,更适合编制索引。

[En]

For example, for a user table, birthdays are more differentiated than gender and are more suitable for indexing.

您可以使用以下方法手动统计每个字段的差异。该值越大,差异化程度越高:

[En]

You can use the following method to manually count the differentiation of each field. The higher the value, the higher the differentiation:

select
    count(distinct birthday)/count(*),
    count(distinct gender)/count(*)
from user;

精心总结十三条建议,帮你创建更合适的MySQL索引

对于已经创建好的索引,我们还可以使用MySQL命令查看每个索引的区分度排名:

精心总结十三条建议,帮你创建更合适的MySQL索引

图中 Cardinality列表示索引的区分度排名,也被称为基数。

2.4 有序的字段适合创建索引

有序的字段在插入数据库的过程中,仍能保持B+树的索引结构,不需要频繁更新索引文件,性能更好。

3. 哪些字段不合适创建索引?

在说明了哪些字段适合创建索引之后,还有一些字段不适合创建索引。

[En]

After saying which fields are suitable for creating an index, there are fields that are not suitable for creating an index.

3.1 区分度低的字段不适合创建索引。

我只是说,用户表中的性别区别较小,因此不像生日字段那样适合创建索引。

[En]

I just said that the gender in the user table is less differentiated, so it is not as suitable for creating an index as the birthday field.

3.2 频繁更新的字段不适合创建索引

更新字段的过程中,需要维护B+树结构,会频繁更新索引文件,降低SQL性能。

3.3 过长的字段不适合创建索引

过长的字段会占用更多空间,不适合创建索引。

[En]

Fields that are too long take up more space and are not suitable for index creation.

3.4 无序的字段不适合创建索引

无序的字段在插入数据库的过程中,为了维护B+树索引结构,需要频繁更新索引文件,性能较差。

4. 创建索引的其他注意事项

4.1 优先使用联合索引

在查询时,联邦索引可以比普通索引更准确地匹配所需的数据。

[En]

When querying, the federated index can match the required data more accurately than the ordinary index.

精心总结十三条建议,帮你创建更合适的MySQL索引

图中就是在(age,name)两个字段上建立的联合索引,在B+树中的存储结构。

可以看出,是先age排序,age相等的数据,再按name排序。

对于这条查询SQL:

select age,name from user where age=18 and name='李四';

联合索引只需一次就可以查到所需数据,如果我们只在age字段上建立索引,会先匹配到age=18的三条数据,然后再逐个遍历,效率更差,所以平时应该优先使用联合索引。

4.2 使用联合索引时,区分度的字段放前面

这将减少查询次数,并更快地匹配所需数据。

[En]

This reduces the number of queries and matches the required data more quickly.

4.3 过长字符串可以使用前缀索引

例如,在匹配用户地址时,如果乡镇已经能区分大部分用户,就不一定要准确到邻里。

[En]

For example, when matching user addresses, if the township can already distinguish most of the users, it is not necessary to be accurate to the neighborhood.

创建普通索引时,指定索引长度,即可创建前缀索引。

[En]

When creating a normal index, specify the index length, and you can create a prefix index.

ALTER TABLE user ADD INDEX idx_address (address(3));

4.4 值唯一的字段,使用唯一索引

使用唯一索引,可以避免程序bug导致产生重复数据。

4.5 排序和分组字段也尽量创建索引

在order by和group by中的字段也尽量创建索引,避免使用文件排序,可以使用索引排序提供性能。

4.6 避免创建过多索引

索引好用,适度即可。创建过多的索引,会占用更多存储空间,也会严重影响SQL性能,每次更新SQL,都需要更新大量索引文件,得不偿失。

知识点总结:

精心总结十三条建议,帮你创建更合适的MySQL索引

文章持续更新,可以微信搜一搜「 一灯架构 」第一时间阅读更多技术干货。

Original: https://www.cnblogs.com/yidengjiagou/p/16538652.html
Author: 一灯架构
Title: 精心总结十三条建议,帮你创建更合适的MySQL索引

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/505115/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • git仓库push 和 pull只获取部分文件的方法

    gitee项目https://gitee.com/kehaoo/mytest目录结构如下其中part1.txt和part2.txt都是内容都是空的 在另一个文件夹将项目part1文…

    数据库 2023年6月11日
    092
  • Java中的命名规则

    在查找java命名规则时,未在国内相关网站查找到较为完整的文章,这是一篇国外程序开发人员写的java命名规则的文章,原文是英文写的,为了便于阅读,遂翻译为汉语,以便帮助国内开发者有…

    数据库 2023年6月11日
    075
  • eclipse连接MySQL 8.0.29.0

    推荐文章: eclipse导入JDBC MySQL详细安装 菜鸟java MySQL连接教程 步骤: 找到MySQL的连接Java的jar文件; 如下图: 在eclipse项目文件…

    数据库 2023年5月24日
    0100
  • 21浙比武

    可以将获得的windows镜像先挂载获取SAM和SYSTEM注册表文件,然后使用mimikatz 提取windows的密码ntml哈希值 <span class=”ne-te…

    数据库 2023年6月11日
    072
  • CMD 命令汇总

    CMD 常用命令 常用命令 作用 D: 切换到 D 盘下 dir 查看当前路径下的全部内容 cd 盘符:\目录1\目录2…… 进入多级目录 cd .. 回退…

    数据库 2023年6月6日
    058
  • Redis和Mysql保持数据一致性

    1、简述 在高并发的场景下,大量的请求直接访问Mysql很容易造成性能问题。所以,我们都会用Redis来做数据的缓存,削减对数据库的请求。但是,Mysql和Redis是两种不同的数…

    数据库 2023年6月16日
    079
  • Flume和 Sqoop

    vim flume-dir-hdfs.conf 添加如下内容 a3.sources = r3 a3.sinks = k3 a3.channels = c3 Describe/con…

    数据库 2023年6月16日
    075
  • html学习笔记

    学完html基本以后,现在对html知识做以下总结: 以上内容来源于bilibiliup狂神说 html html,即超文本标记语言(Hyper Text Markup Langu…

    数据库 2023年6月14日
    076
  • 使用REST风格完成MVC前后端分离

    一个具有REST风格项目的基本特征: 使用REST框架实现前后端分离架构,我们需要首先确定返回的JSON响应结构是统一的,也就是说,每个REST请求将返回相同结构的JSON响应结构…

    数据库 2023年6月11日
    0101
  • [springmvc]从前端获取参数以及显示

    6.接收请求参数以及数据回显 接收普通参数 参数名与前端传递的参数名相同时 前端表单名name=name $Title$ username: 后端收到的参数名String name…

    数据库 2023年6月16日
    090
  • 西数数码-安装hmx_linux下的环境记录

    [nginx]name=nginx repobaseurl=http://nginx.org/packages/centos/6/x86_64/gpgcheck=0enabled=…

    数据库 2023年6月14日
    045
  • 0811JDBC随笔

    1.JDBC体系系统 一组规范:接口 JDBC接口(API)包括两个层次: 面向应用的API:Java API,抽象接口,供应用开发人员使用(连接数据库,执行SQL语句,获得结果)…

    数据库 2023年5月24日
    064
  • Jenkins权限配置

    Jenkins权限配置 需要的插件 一、添加用户 二、修改配置 三、管理添加角色 添加全局查看角色 给全局角色添加用户(Anonymous-任何人) 添加角色(全局,项目) 检查项…

    数据库 2023年6月11日
    070
  • LeetCode 344. 反转字符串

    编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 //输入一个字符串,输出它的倒序字符串 input: Hello output: olleH …

    数据库 2023年6月11日
    078
  • 总监让我当小组长,我不愿意,理由竟是…

    来源:BiggerBoy作者:北哥原文链接:https://mp.weixin.qq.com/s/_pkjvDzGQUDTfo9C1bieJw 最近看到一个话题,热度很高:【总监让…

    数据库 2023年6月11日
    066
  • 我的第一次校招

    2018-09-26 23:40:03 虽然是第一次参加,但这次的笔试完成结果让我不是很满意,因为有几道超简单的字符串编程没有做,忘了或者是想复杂了,还有一些概念题不是很清楚,自己…

    数据库 2023年6月16日
    0107
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球