玩转Mysql系列 - 第23篇:mysql索引管理详解

news2024/11/26 1:35:33

这是Mysql系列第23篇。

环境:mysql5.7.25,cmd命令中进行演示。

代码中被[]包含的表示可选,|符号分开的表示可选其一。

关于索引的,可以先看一下前2篇文章:

  1. 什么是索引?

  2. mysql索引原理详解

本文主要介绍mysql中索引常见的管理操作。

索引分类

分为聚集索引非聚集索引

聚集索引

每个表有且一定会有一个聚集索引,整个表的数据存储在聚集索引中,mysql索引是采用B+树结构保存在文件中,叶子节点存储主键的值以及对应记录的数据,非叶子节点不存储记录的数据,只存储主键的值。当表中未指定主键时,mysql内部会自动给每条记录添加一个隐藏的rowid字段(默认4个字节)作为主键,用rowid构建聚集索引。

聚集索引在mysql中又叫主键索引

非聚集索引(辅助索引)

也是b+树结构,不过有一点和聚集索引不同,非聚集索引叶子节点存储字段(索引字段)的值以及对应记录主键的值,其他节点只存储字段的值(索引字段)。

每个表可以有多个非聚集索引。

mysql中非聚集索引分为
单列索引

即一个索引只包含一个列。

多列索引(又称复合索引)

即一个索引包含多个列。

唯一索引

索引列的值必须唯一,允许有一个空值。

数据检索的过程

看一张图:

图片

上面的表中有2个索引:id作为主键索引,name作为辅助索引。

innodb我们用的最多,我们只看图中左边的innodb中数据检索过程:

如果需要查询id=14的数据,只需要在左边的主键索引中检索就可以了。

如果需要搜索name='Ellison'的数据,需要2步:

  1. 先在辅助索引中检索到name='Ellison'的数据,获取id为14

  2. 再到主键索引中检索id为14的记录

辅助索引相对于主键索引多了第二步。

索引管理

创建索引
方式1:
create [unique] index 索引名称 on 表名(列名[(length)]);
方式2:
alter 表名 add [unique] index 索引名称 on (列名[(length)]);

如果字段是char、varchar类型,length可以小于字段实际长度,如果是blog、text等长文本类型,必须指定length。

[unique]:中括号代表可以省略,如果加上了unique,表示创建唯一索引。

如果table后面只写一个字段,就是单列索引,如果写多个字段,就是复合索引,多个字段之间用逗号隔开。

删除索引
drop index 索引名称 on 表名;
查看索引

查看某个表中所有的索引信息如下:

show index from 表名;
索引修改

可以先删除索引,再重建索引。

示例

准备200万数据
/*建库javacode2018*/
DROP DATABASE IF EXISTS javacode2018;
CREATE DATABASE javacode2018;
USE javacode2018;

/*建表test1*/
DROP TABLE IF EXISTS test1;
CREATE TABLE test1 (
  id     INT NOT NULL COMMENT '编号',
  name   VARCHAR(20) NOT NULL COMMENT '姓名',
  sex TINYINT NOT NULL COMMENT '性别,1:男,2:女',
  email  VARCHAR(50)
);

/*准备数据*/
DROP PROCEDURE IF EXISTS proc1;
DELIMITER $
CREATE PROCEDURE proc1()
  BEGIN
    DECLARE i INT DEFAULT 1;
    START TRANSACTION;
    WHILE i <= 2000000 DO
      INSERT INTO test1 (id, name, sex, email) VALUES (i,concat('javacode',i),if(mod(i,2),1,2),concat('javacode',i,'@163.com'));
      SET i = i + 1;
      if i%10000=0 THEN
        COMMIT;
        START TRANSACTION;
      END IF;
    END WHILE;
    COMMIT;
  END $

DELIMITER ;
CALL proc1();
SELECT count(*) FROM test1;

上图中使用存储过程循环插入了200万记录,表中有4个字段,除了sex列,其他列的值都是没有重复的,表中还未建索引。

插入的200万数据中,id,name,email的值都是没有重复的。

无索引我们体验一下查询速度
mysql> select * from test1 a where a.id = 1;
+----+-----------+-----+-------------------+
| id | name      | sex | email             |
+----+-----------+-----+-------------------+
|  1 | javacode1 |   1 | javacode1@163.com |
+----+-----------+-----+-------------------+
1 row in set (0.77 sec)

上面我们按id查询了一条记录耗时770毫秒,我们在id上面创建个索引感受一下速度。

创建索引

我们在id上面创建一个索引,感受一下:

mysql> create index idx1 on test1 (id);
Query OK, 0 rows affected (2.82 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> select * from test1 a where a.id = 1;
+----+-----------+-----+-------------------+
| id | name      | sex | email             |
+----+-----------+-----+-------------------+
|  1 | javacode1 |   1 | javacode1@163.com |
+----+-----------+-----+-------------------+
1 row in set (0.00 sec)

上面的查询是不是非常快,耗时1毫秒都不到。

我们在name上也创建个索引,感受一下查询的神速,如下:

mysql> create unique index idx2 on test1(name);
Query OK, 0 rows affected (9.67 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> select * from test1 where name = 'javacode1';
+----+-----------+-----+-------------------+
| id | name      | sex | email             |
+----+-----------+-----+-------------------+
|  1 | javacode1 |   1 | javacode1@163.com |
+----+-----------+-----+-------------------+
1 row in set (0.00 sec)

查询快如闪电,有没有,索引是如此的神奇。

创建索引并指定长度

通过email检索一下数据

mysql> select * from test1 a where a.email = 'javacode1000085@163.com';
+---------+-----------------+-----+-------------------------+
| id      | name            | sex | email                   |
+---------+-----------------+-----+-------------------------+
| 1000085 | javacode1000085 |   1 | javacode1000085@163.com |
+---------+-----------------+-----+-------------------------+
1 row in set (1.28 sec)

耗时1秒多,回头去看一下插入数据的sql,我们可以看到所有的email记录,每条记录的前面15个字符是不一样的,结尾是一样的(都是@163.com),通过前面15个字符就可以定位一个email了,那么我们可以对email创建索引的时候指定一个长度为15,这样相对于整个email字段更短一些,查询效果是一样的,这样一个页中可以存储更多的索引记录,命令如下:

mysql> create index idx3 on test1 (email(15));
Query OK, 0 rows affected (7.67 sec)
Records: 0  Duplicates: 0  Warnings: 0

然后看一下查询效果:

mysql> select * from test1 a where a.email = 'javacode1000085@163.com';
+---------+-----------------+-----+-------------------------+
| id      | name            | sex | email                   |
+---------+-----------------+-----+-------------------------+
| 1000085 | javacode1000085 |   1 | javacode1000085@163.com |
+---------+-----------------+-----+-------------------------+
1 row in set (0.00 sec)

耗时不到1毫秒,神速。

查看表中的索引

我们看一下test1表中的所有索引,如下:

mysql> show index from test1;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test1 |          0 | idx2     |            1 | name        | A         |     1992727 |     NULL | NULL   |      | BTREE      |         |               |
| test1 |          1 | idx1     |            1 | id          | A         |     1992727 |     NULL | NULL   |      | BTREE      |         |               |
| test1 |          1 | idx3     |            1 | email       | A         |     1992727 |       15 | NULL   | YES  | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.00 sec)

可以看到test1表中3个索引的详细信息(索引名称、类型,字段)。

删除索引

我们删除idx1,然后再列出test1表所有索引,如下:

mysql> drop index idx1 on test1;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show index from test1;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test1 |          0 | idx2     |            1 | name        | A         |     1992727 |     NULL | NULL   |      | BTREE      |         |               |
| test1 |          1 | idx3     |            1 | email       | A         |     1992727 |       15 | NULL   | YES  | BTREE      |         |               |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
2 rows in set (0.00 sec)

本篇主要是mysql中索引管理相关一些操作,属于基础知识,希望大家掌握。

下篇文章介绍:

  1. 一个表应该创建哪些索引?

  2. 有索引时sql应该怎么写?

  3. 我的sql为什么不走索引?需要知道内部原理

  4. where条件涉及多个字段多个索引时怎么走?

  5. 多表连接查询、子查询,怎么去利用索引,内部过程是什么样的?

  6. like查询中前面有%的时候为何不走索引?

  7. 字段中使用函数的时候为什么不走索引?

  8. 字符串查询使用数字作为条件的时候为什么不走索引?、

  9. 索引区分度、索引覆盖、最左匹配、索引排序又是什么?原理是什么?

关于上面各种索引选择的问题,我们会深入其原理,让大家知道为什么是这样?而不是只去记一些优化规则,而不知道其原因,知道其原理用的时候更加得心应手一些。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1042856.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Sui资助申请指南,310万美元资助金已成功申领

Sui基金会致力于资助开发者、构建者、教育工作者、研究人员以及其他推动和推广Sui生态发展的社区成员。立即申请&#xff1a;https://airtable.com/shrkLWBRNPL89f0SX 资助计划类型 构建者资助计划 通过推动Sui的全球采用&#xff0c;帮助引导下一个十亿用户进入Web3的项目。…

外包干了3个月,技术退步明显。。。。。

先说一下自己的情况&#xff0c;大专生&#xff0c;17年通过校招进入广州某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

使用 Microsoft 365 进行移动设备管理

什么是 Microsoft 365 的移动设备管理 移动设备通过允许员工访问文件、电子邮件、联系人等&#xff0c;在帮助员工随时随地工作方面发挥了巨大作用&#xff0c;允许员工将公司拥有的移动设备用于工作目的可能意味着允许员工在不在办公场所时从外部网络访问资源&#xff0c;这使…

人工智能在医疗中的应用:医院陪诊系统的前沿技术

人工智能在医疗领域的应用已经带来了巨大的变革&#xff0c;其中之一是医院陪诊系统。这些系统利用机器学习和自然语言处理等人工智能技术&#xff0c;改善了患者体验&#xff0c;提高了医疗机构的效率。本文将讨论医院陪诊系统的前沿技术&#xff0c;并提供一个简单的示例代码…

密码学【第三节:对称密码-DES\AES】

前言 在密码学中&#xff0c;加密算法分为双向加密和单向加密。单向加密包括MD5、SHA等摘要算法&#xff0c;它们是不可逆的。双向加密包括对称加密和非对称加密&#xff0c;对称加密包括AES加密、DES加密等。双向加密是可逆的&#xff0c;存在密文的密钥。AES算法是DES算法的替…

Java 大厂八股文面试专题-JVM相关面试题 类加载器

Java 大厂八股文面试专题-设计模式 工厂方法模式、策略模式、责任链模式-CSDN博客 JVM相关面试题 1 JVM组成 1.1 JVM由那些部分组成&#xff0c;运行流程是什么&#xff1f; 难易程度&#xff1a;☆☆☆ 出现频率&#xff1a;☆☆☆☆ JVM是什么 Java Virtual Machine Java程序…

openGauss学习笔记-81 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT使用概述

文章目录 openGauss学习笔记-81 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT使用概述 openGauss学习笔记-81 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT使用概述 MOT作为openGauss的一部分自动部署。有关如何计算和规划所需的内存和存储资源以维持工…

Vue watch实时计算器

watch实时计算器 可以自己选择、-、*、 参考代码 <!DOCTYPE html> <html> <head><meta charset"utf-8"><title></title><script src"https://cdn.bootcdn.net/ajax/libs/vue/2.7.10/vue.js"></script>…

Redis安装部署和常用命令

文章目录 一、关系数据库与非关系型数据库1.1 关系型数据库1.2 非关系型数据库1.3 关系型数据库和非关系型数据库区别1.4 非关系型数据库产生背景1.5 小结 二、Redis基本概念2.1 Redis 简介2.2 Redis的优点2.3 使用场景2.4 哪些数据适合放入缓存中&#xff1f;2.5 Redis的数据类…

2015-2022年商道融绿 ESG数据

2015-2022年商道融绿 ESG数据 1、时间&#xff1a;2015-2022年 2、指标&#xff1a;证券代码、证券简称、商道融绿ESG评级 3、范围&#xff1a;沪深A股上市公司 4、来源&#xff1a;整理自wind 5、指标解释&#xff1a; 商道融绿&#xff08;Sustainalytics&#xff09;E…

【Flink、java】

依赖 <dependency><groupId>org.apache.flink</groupId><artifactId>flink-streaming-java_2.11</artifactId><version>1.14.6</version></dependency><dependency><groupId>org.apache.flink</groupId>&…

jenkins流水线实现xjar加固

jenkins流水线实现xjar加固 xjar的定义 Spring Boot JAR 安全加密运行工具&#xff0c;同时支持的原生JAR。 基于对JAR包内资源的加密以及拓展ClassLoader来构建的一套程序加密启动&#xff0c;动态解密运行的方案&#xff0c;避免源码泄露或反编译功能特性 无需侵入代码&am…

nvm nodejs的版本管理工具

nvm 全英文名叫 node.js version management&#xff0c;是一个 nodejs 的版本管理工具&#xff0c;为了解决 nodejs 各种版本存在不兼容现象可以通过他安装和切换不同版本的 nodejs。 一、完全删除之前的 node 和 npm 1. 打开 cmd 命令窗口&#xff0c;输入 npm cache clean…

rs渲染VRAM内存不足怎么解决?Redshift 处理 VRAM 不足的情况

在某些极少数情况下&#xff0c;Redshift 可能会生成以下类型的消息并中止渲染&#xff1a; Redshift cannot operate with less than 256MB of free VRAM. Frame rendering aborted. 或者… There is less than 128MB of free VRAM once fixed data and minimal ray memory ar…

用简单例子讲清楚webgl模板测试

文章目录 搭建简易的webgl环境绘制简单三角形&#xff08;不带stencilTest)绘制另一个三角形&#xff08;不带模板测试&#xff09;加入模板测试总结调参练习 搭建简易的webgl环境 一直以来&#xff0c;我只是想通过搭建纯webgl环境&#xff0c;进行开发&#xff0c;来清楚地了…

计算机毕业设计 基于微信小程序的学习资料销售平台的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

IP地址最终弹,DNS,数据链路层,特殊地址

目录 一、特殊地址 二、数据链路层 三、DNS 一、特殊地址 将IP地址中的主机IP全部设置为0&#xff0c;就成了网络号&#xff0c;代表这个局域网&#xff08;不可给具体的设备分配这个IP&#xff09; 将IP地址中的主机IP全部设置为1&#xff0c;就成了广播地址&#xff0c;给同…

灰色预测GM(1,1)

目录 一、灰色预测模型简介 二、GM(1,1)灰色模型 1、GM(1,1)模型预测方法 &#xff08;1&#xff09;原始数据&#xff08;参考列&#xff09; &#xff08;2&#xff09;累加生成序列&#xff08;Acumulated Generating Operator,1-AGO&#xff09; &#xff08;3&#xff…

一台电脑安装多个不同版本Python

1、前提 当前Windows电脑下已经安装了一个python3.11&#xff0c;现在需要安装一个python3.9。下载地址&#xff1a;Python Releases for Windows | Python.org 2、步骤 找到对应的版本&#xff0c;并下载安装包。下载后&#xff0c;打开安装包。按图片勾选&#xff0c;点击n…