【进阶】MySQL索引介绍

news2024/11/17 5:46:33

半个月没写mysql了,今天记录一下。。

了解到的索引有B+tree,Hash表(Memory存储引擎中),R-tree,Full-text等

MySql用的索引结构是B+tree,B+树所有节点都会出现在叶子节点中

目录

索引介绍:

索引分类:

聚集索引选取规则:

索引语法

索引的性能分析

验证索引效率

索引的使用规则

索引失效情况

SQL提示

覆盖索引&回表查询

前缀索引

单列索引和联合索引的选取

索引设计原则


索引介绍:

是有效的数据结构,位于存储引擎层,能够提高检索效率,降低数据库的io成本,但是同时索引是要占有空间的,索引会降低更新表的速度,如对表进行insert,update,delete等效率降低

索引分类

市面上常见索引:主键索引(只能有1个),二级索引,唯一索引(可以有多个),常规索引,全文索引。

在MySQL默认存储引擎是Innodb,Innodb存储引擎中根据索引结构分为了聚集索引和二级索引。每张表都必须有且仅有1个聚集索引(id),聚集索引的叶子节点下面挂的是表格某一行的数据(row);二级索引的叶子节点关联的是对应的主键,可存在多个。

 

 

聚集索引选取规则:

聚集索引在innodb中必须存在

1.若存在主键,主键索引就是聚集索引

2.若无主键,使用第一个唯一索引作为聚集索引

3.若无主键也无唯一索引,innodb自动生成一个rowid作为隐藏的聚集索引

索引语法

1.创建

create [unique/fulltext]  index 索引名 on 表格名(索引的字段可多个,单个字段是单列索引,多个字段就变成联合索引);

2.展示

show index from 表格名;

3.删除

drop index 索引名 on 表格名;

索引的性能分析

1.查看执行的频次,通过下面指令可以查看数据库的insert,update,delete,select访问频次

show global status like ’com_______';   #7个_

2.慢日志查询(这个要修改linux系统下的my.cnf,不太建议尝试,因为可能重启后连不上mysql,我就是这样)

慢日志记录了所有执行时间超过指定参数化(默认是10s)的所有sql语句

#查询慢日志是否开启

show variables like 'slow_query_log';

vim /etx/my.cnf

#开启慢日志查询,1为开启,0为关闭

show_query_log=1;

#重启mysql

systemctl restart mysqld

进入下面目录查看生成的日志localhost-slow.log

cd /var/lib/mysql

3.通过profiles文件

profiles能够帮助我们知道执行时间多耗费在哪些sql语句

#先要检查下是否支持profiles操作

select @@have_profiling;

#是否开启开关

select @@profiling;   #0表示关

set profiling=1;   #开启

#查看每条sql的基本耗时情况

show profiles; 

#查看指定id的sql语句的基本耗时情况

show profile for query queryid;

4.通过explain关键字查看语句执行信息

explain或desc命令获取mysql如何执行select语句的信息

语法:explain select 字段列表 from 表名 where 条件;

explain各字段含义:

id:表示查询中执行select子句或操作表的顺序(id相同,从上往下执行);id不同先执行id值大的

select_type:表示select的类表示连接的类型

type:表示连接类型,性能有好到差的连接类型为null,system,const,eq_ref,ref,range,index,all;

possible_keys:可能用到的索引

key:实际用到的索引

key_len:索引中使用的字节数,为索引字段最大可能长度,但并非实际使用长度

ref:子查询返回类型

rows:MySQL认为必须执行的行数,在innodb引擎的表中,是1个估计值

filtered:返回结果的行数占需要读取行数的百分比 ,该值越大越好

验证索引效率

假如表中有100w条数据,通过索引查询指定记录比通过普通字段查询指定记录要快很多

索引的使用规则

1.联合索引的最左前缀法则

3个字段的索引长度

例如针对3个字段建立索引,在查询数据时候最左边的字段必须存在(但是放的位置无所谓),才会走联合索引;同时如果查询时只有最左边和最右边的字段,忽略中间的字段,那么虽然还是会走联合索引但只有最左边的索引字段生效的

 

2.范围查询

联合索引中,出现范围查询(>,<),范围查询右侧的列索引会失效~~

例如前者使用范围查询>,因此and后面的索引字段失效了,后者使用范围查询>=但是 and后面的索引字段没有失效

索引失效情况

1.索引列运算(对某字段运用了函数):

不要在索引列上进行运算操作,否则索引失效

如:我们对字段phone利用substrin截取查询后索引就失效了

 2.字符串不加单引号,索引失效

如字段phone本来 是varchar类型,查询时不加单引号后索引失效

 

3.模糊查询

如果仅仅是尾部模糊查询,索引不会失效,但是如果是头部模糊查询,索引失效;头尾都模糊也失效 

4.or连接

如下面因为age没有索引,索引查询不会走索引, 解决方法是给字段age增加索引

5.数据分布影响

如范围查询时,如果表中大部分数据都满足范围查询,mysql会自己去评估如果全表扫描比走索引更快些,就 直接全表扫描;如果表中大部分数据都不满足范围查询,mysql会自己去评估全表扫描还是走索引更快些,然后走索引

 

再如由于表中没有null的字段,因此通过is null查询时走索引,通过is not null查询时走全表扫描

SQL提示

是优化数据库的重要手段,就是在sql语句中加入一些认为提示,如果一个字段既含有单列索引还有联合索引,可以人为干预让mysql走不走某个索引

use index:建议mysql走我们指定的索引(mysql不一定会接受我们的建议)

语法:select 字段名 from 表名 use index(索引名) where xx;

ignore index:让mysql忽略某个索引

语法:select 字段名 from 表名 ignore index(索引名) where xx;

force index:强制mysql走我们指定的索引

语法:select 字段名 from 表名 force index(索引名) where xx;

覆盖索引&回表查询

前者using where;using index说明使用了索引,且需要的数据在索引列都能找到,不需要回表查询

后者using index condition说明使用了索引,但也走了回表查询,效率较前者更低。

覆盖索引查询使用到了索引,且不需要回表就能返回我们想要的列,在该索引中能全部找到,那么该索引为覆盖索引,我们应该尽量使用覆盖索引。

 如果要查询的某些字段通过辅助索引拿不到,那就需要拿到辅助索引下面的主键id然后回表查询到叶子节点下的row(row中包含了此id记录的所有数据)

 思考:

 二级索引下面会存放主键id,所以针对字段username和password建立联合索引即可

前缀索引

如果字段类型为字符串(varchar,text等),有时候需要索引很长的字符串,这会让索引变得很大,查询时浪费大量的磁盘io,影响查询效率,此时可以只将字符串的一部分前缀建立索引,这样可以大大节约索引空间,从而提高索引效率。

语法:

create index 索引名 on 表名(字段名(n))  --n表示取字段前n位

创建前缀索引时,前缀长度可以考虑选择性和索引体积大小间的权衡问题,

如字段email的前5个字符和前六个字符的选择性都是0.9583,这种时候可以选择前五个字符创建前缀索引,节省索引体积大小

 前缀索引查询流程 :

主键会建立聚集索引,我们创建的前缀索引会建立辅助索引(也叫二级索引,也叫非聚集索引),首先在辅助索引中查询到"lvbu6",拿到对应id后回表查询拿到row记录,然后mysql核实row中的数据是不是我们查询要的数据("lvbu666@163.com"),然后会再回到辅助索引中继续查找看还有没有"lvbu6",有则再次回表然后核实row,最后将核实好的所有row组装返回。

单列索引和联合索引的选取

单列索引:一个索引只包含一个列

联合索引:一个索引包含多个列

在业务场景中,如果存在多个查询条件,考虑针对于查询字段建立索引时,建议建立联合索引,而非单列索引;在多条件查询时,mysql优化器会评估哪个字段的索引效率更高,选择该索引完成本次的查询

例如 我们对字段phone,字段name分别建立单列索引,对字段phone和name建立联合索引,下面演示前者的extra列是null,说明是走了回表查询,而后者是走了索引

索引设计原则

 

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

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

相关文章

容器目录挂载原理

前言 就我目前的对容器的了解, 使用namespace技术实现隔离, 使用cgroups技术实现资源限制. 但是具体是如何实现却从未深究过. 闲来无事, 挑其中的Mount Namespace来康康, 容器是如何实现目录隔离的. 目录隔离 在耗子叔的这篇文章中对此技术进行了介绍. 在c函数库中, 可通过…

Linux Audio (4) ASOC代码分析-基于kernel3.4.2

ASOC代码分析-基于kernel3.4.2 OverviewPlatformCPU DAICPU DMA CodecMechine Linux kernel版本&#xff1a;3.4.2 Overview linux ASoC音频设备驱动 ASoC是ALSA在SoC方面的发展和演变&#xff0c;它的本质仍然属于ALSA&#xff0c;但是在ALSA架构基础上对CPU相关的代码和Cod…

【python之django1.11框架一】django环境搭建及基本操作

1. 环境准备 开发环境&#xff1a;windows 11先安装好miniconda3。镜像地址&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/ 选择windows 64位下载。 下载地址&#xff1a; https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-lates…

JIRA的数据备份与恢复教程

目录 一、简介 二、数据备份&#xff08;默认系统会自动备份&#xff0c;不需要手动&#xff09; 1、使用管理员账号登录JIRA。 2、点击左上角的设置按钮&#xff0c;选择“系统”选项。 3、选择“备份系统”选项 4、开始手动备份 5、查看备份进度 三、数据恢复 1、使用…

MyBatisPlus入门案例

文章目录 1 入门案例步骤1:创建数据库及表步骤2:创建SpringBoot工程步骤3:勾选配置使用技术步骤4:pom.xml补全依赖步骤5:添加MP的相关配置信息步骤6:根据数据库表创建实体类步骤7:创建Dao接口步骤8:编写引导类步骤9:编写测试类 2 MybatisPlus简介 MyBatisPlus主要是对MyBatis的…

SQL注入 - Part 1

前置知识&#xff1a;sql前置的软件环境&#xff1a;预装了phpstudy_prodvwa&#xff0c;花了好长时间……时间主要浪费在听从chatgpt的建议装xampp上&#xff0c;卸载了mysql&#xff0c;重置了密码。其实使用xampp搭建环境也成功了&#xff0c;但是由于phpstudy教程比较多&am…

了解物理层下的传输媒体

1.了解物理层下的传输媒体 声明&#xff1a;该学习笔记来自湖科大教书匠&#xff0c;笔记仅做学习参考 笔记来源&#xff1a; 湖科大教书匠&#xff1a;物理层的基本概念 湖科大教书匠&#xff1a;物理层下面的传输媒体 1.1 物理层的基本概念 物理层考虑在连接各计算机的传输…

JQuery原理剖析——自己手写简易版JQuery

目录 为什么需要JQuery 在此之前回顾JavaScript对象知识&#xff1a; 自己手写的简易JQuery&#xff1a; 为什么需要JQuery 在我们之前写的JS代码中经常会遇见document.getElementById等等获取元素的对象&#xff0c;当大量的元素对象需要被获取时&#xff0c;就会有很多相似…

linux系统升级/更新OpenSSL版本操作流程记录

问题描述&#xff1a;有时 OpenSSL 版本过老升级&#xff0c;或者需要更新 OpenSSL 版本 1. 登录 linux 系统后输入 openssl version 查看现在使用的版本 我的输入后版本信息为&#xff1a;OpenSSL 1.1.1g FIPS 21 Apr 2020 &#xff0c;可以看到是一年前更新版本&#xff0c;…

openGauss数据库Package原理分析FAQ

FAQ的形式分析OpenGauss中package实现基础关键逻辑。 下面四个问题基本将市面上基于postgresql实现package的方法分成了几类。 例如问题一&#xff1a; openGauss使用包所在的namespace作为包函数的namespace。IvorySQL使用包本身的oid作为包函数的namespace。还有db创建一个…

微信小程序vue+nodejs校园快递物流取件及上门服务系统uniapp

系统分为用户和管理员两个角色 用户的主要功能有&#xff1a; 1.用户注册和登陆系统 2.用户查看系统的公告信息 3.用户在线快递下单&#xff0c;支付订单&#xff0c;在线订购快递取件 4.用户在线预约快递&#xff0c;填写快递预约信息 5.用户个人中心在线充值 6.用户个人中心修…

c++学习——概述、命名空间注意事项

C语言在c语言的基础上添加了面向对象编程和泛型编程的支持。 第一个helloworld #define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std;//标准命名空间int main() {//cout是标准的输出流对象&#xff0c;打印字符串//endl是刷新缓冲区&#xff0c;…

软件详细设计总复习(一)【太原理工大学】

实验内容重点看&#xff0c;无需死记&#xff0c;它更是一种设计思想。要理解一种设计模式出现的意义是什么&#xff0c;它又是如何方便我们使用的&#xff1f;目的无非就是解耦、易扩充。题目问到优缺点&#xff0c;你只要知道该模式的设计思想就完全可以用自己的话概述&#…

chatgpt赋能Python-python3绘制图形

Python3绘制图形 – 让数据更加生动 作为一种可视化数据的工具&#xff0c;图形在数据分析和展示中扮演着重要的角色。Python3作为一种高效的编程语言&#xff0c;在图形方面也有自己的实现方式&#xff0c;让我们一起来了解Python3的图形绘制。 什么是Python3图形绘制&#…

chatgpt赋能Python-python3_取余

Python3 取余 在Python3中&#xff0c;取余运算是使用%符号进行实现的。它可以用于整数和浮点数&#xff0c;并返回一个余数。Python3是一种开放源码、高级编程语言。它是一种解释型语言&#xff0c;由于其简洁的语法和易于阅读的特性而受到广泛的欢迎。 取余基础 取余运算就…

ContOS7单机安装Hadoop

安装Hadoop 1&#xff0c;准备环节 因为Hadoop是由java编写的&#xff0c;所以需要Java的环境支持&#xff0c;作为开发者我们需要安装jdk。 安装jdk的教程http://t.csdn.cn/6qJKg 下载Hadoop的安装包 Hadoop官网&#xff1a;http://hadoop.apache.org/ Hadoop版本下载地…

【连续介质力学】张量的偏微分、球张量和偏张量

张量的偏微分 张量的一阶微分&#xff0c;定义&#xff1a; ∂ A ∂ A A , A ∂ A i j ∂ A k l ( e ^ i ⨂ e ^ j ⨂ e ^ k ⨂ e ^ l ) δ i k δ j l ( e ^ i ⨂ e ^ j ⨂ e ^ k ⨂ e ^ l ) I \frac{\partial A}{\partial A} A_{,A}\frac{\partial A_{ij}}{\partial A…

C++ map用法总结(整理)

1&#xff0c;map简介 map是STL的一个关联容器&#xff0c;它提供一对一的hash。 第一个可以称为关键字(key)&#xff0c;每个关键字只能在map中出现一次&#xff1b;第二个可能称为该关键字的值(value)&#xff1b; map以模板(泛型)方式实现&#xff0c;可以存储任意类型的…

算法26:暴力递归

目录 题目1&#xff1a;给你一个字符串&#xff0c;要求打印打印出这个字符串的全部子序列&#xff08;子序列不能重复&#xff09; 题目2&#xff1a;打印一个字符串的全部排列。 题目3&#xff1a;针对题目2&#xff0c;要求去除重复元素 题目4&#xff1a;给定一个字符串…

【靶机】vulnhub靶机billu

靶机下载地址&#xff1a;https://download.vulnhub.com/billu/Billu_b0x.zip 一、环境搭建 1.1 实验环境设计 使用vmware导入靶机&#xff0c;模式为nat模式即可&#xff0c;同时开启kali作为攻击机&#xff0c;对靶机进行渗透&#xff0c;要确定两台主机在同一网段。 Kali…