mysql数据库详解(三):索引与sql优化

MySQL进阶【四】—— MySQL索引优化实战 示例表 CREATE TABLE `employees` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(24) NOT NULL DEFAULT '' COMMENT '姓名', `age` int(11) NOT NULL DEFAULT '0' COMMENT '年龄', `position` varchar(20) NOT NULL DEFAULT '' COMMENT '职位', `hire_time` timestamp NO 阅读详情

作为一个稀有的Java妹子,所写的所有博客都只是当作自己的笔记,留下证据自己之前是有用心学习的~哈哈哈哈(如果有不对的地方,也请大家指出,不要悄悄咪咪的不告诉我)

一、索引是什么

索引是一种可以高效查询的数据结构。数据库的查询是经常被使用的操作,我们往往希望查询的效率高,如果是按照顺序查找的方法,当数据量变大的时候,查询效率就会变得非常低,所以mysql的开发者设计了索引来优化查询效率。

二、索引的结构

索引根据数据库的引擎可以分为很多种,B-tree,HASH,全文索引等,mysql主要是使用了B-tree,所以这篇主要介绍B-tree结构。

B-tree结构

从名字上可以看出这是一种树型结构,有根节点、叶子节点、非叶子节点,所有的节点存放key和data,key就是索引的值,data存放数据,key的左右都有指针。
在这里插入图片描述

B+tree

B-Tree有许多变种,其中最常见的是B+Tree,例如MySQL就普遍使用B+Tree实现其索引结构。
两者的不同点在于B+tree只有叶子节点有data,其他节点只有key;叶子节点不存储指针
在这里插入图片描述

三、mysql不同的存储引擎索引的区别

1.MyISAM

MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址。主索引和辅助索引的结构是一样的,只是主索引key要求唯一,辅助索引不要求。MyISAM的索引是非聚集的,数据文件和索引文件是分开存放的,先根据索引找到存放数据的地址,再通过地址获取数据。

2.InnoDB

InnoDB引擎也是使用B+tree作为索引结构,不过叶节点的data域存放的是一行完整的数据,并且数据文件本身就是索引文件,也被叫做聚集索引。
在这里插入图片描述

以上两种索引结构叶子节点都有指针,从左至右顺序的连接起来。

因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。
InnoDB的辅助索引的data域存放的是主键,所以根据辅助索引查询时,是先根据辅助索引查询到主键索引,再根据主键索引查询数据。

四、InnoDB中索引的分类

1、主键索引
2、唯一索引
3、普通索引
4、全文索引(没使用过)

因为InnoDB是聚集索引,所以就算不给表建主键也会默认添加,所以一般来讲都会给表设置一个自动递增的主键。

1.联合索引

刚才列举的所有索引都可以建联合索引,联合索引只是涉及多个列,且满足最左原则。比如有这样一个联合索引,(a,b,c)那么只有 a,ab,abc这三种才会使索引生效,b,bc不会使用到索引。因为InnoDB是聚集索引,所以不论索引是在建表时建立的还是建表后数据量大了建立的,数据文件和索引文件都只有一个,即数据是按照索引来存放的,联合索引就是按照a,b,c的顺序来存放的,如果想要用索引,那么第一个匹配的必须是a,然后再是b,最后是c,如果一开始是b,那么根本不会匹配上。

因为mysql有查询优化器,所以就算联合索引是a,b,c,如果where 条件是 b,c,a也会用到联合索引。

2.explain

怎样知道查询有没有用到索引呢,通过explain就可以查到

explain select * from tb_system_user_log where user_id = 13424256

在这里插入图片描述
1、id:sql里每条语句执行的先后顺序,数字越大越先被执行(子查询的情况)
2、select_type:显示sql的复杂程度
3、table:表
4、type:显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL ,一般来说,得保证查询至少达到range级别,最好能达到ref。

system 表只有一行记录(等于系统表),这是const类型的特列,平时不会出现,这个也可以忽略不计
const 表示通过索引一次就找到了,const用于比较primary key 或者unique索引。因为只匹配一行数据,所以很快。如将主键置于where列表中,MySQL就能将该查询转换为一个常量。
eq_ref 唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描
ref 非唯一性索引扫描,返回匹配某个单独值的所有行,本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体。
range 只检索给定范围的行,使用一个索引来选择行,key列显示使用了哪个索引,一般就是在你的where语句中出现between、< 、>、in等的查询,这种范围扫描索引比全表扫描要好,因为它只需要开始于索引的某一点,而结束于另一点,不用扫描全部索引。
index Full Index Scan,Index与All区别为index类型只遍历索引树。这通常比ALL快,因为索引文件通常比数据文件小。(也就是说虽然all和Index都是读全表,但index是从索引中读取的,而all是从硬盘读取的)
all Full Table Scan 将遍历全表以找到匹配的行

5、possible_keys: 显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用。
6、key:实际使用的索引,如果为NULL,则没有使用索引。(可能原因包括没有建立索引或索引失效)
7、key_len表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。用于处理查询的索引长度,如果是单列索引,那就整个索引长度算进去,如果是多列索引,那么查询不一定都能使用到所有的列,具体使用到了多少个列的索引,这里就会计算进去,没有使用到的列,这里不会计算进去。留意下这个列的值,算一下你的多列索引总长度就知道有没有使用到所有的列了。要注意,mysql的ICP特性使用到的索引不会计入其中。另外,key_len只计算where条件用到的索引长度,而排序和分组就算用到了索引,也不会计算到key_len中。在不损失精确性的情况下,长度越短越好。
8、ref:表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值 如果是使用的常数等值查询,这里会显示const,如果是连接查询,被驱动表的执行计划这里会显示驱动表的关联字段,如果是条件使用了表达式或者函数,或者条件列发生了内部隐式转换,这里可能显示为func
9、rows:显示MySQL认为它执行查询时必须检查的行数。注意这是一个预估值。
10、extra:

关键字解释
Distinct在select部分使用了distinc关键字 一旦mysql找到了与行相联合匹配的行,就不再搜索了
no tables used不带from字句的查询或者From dual查询
Using filesort看到这个的时候,查询就需要优化了。mysql需要进行额外的步骤来查询如何对返回row(行)排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行。排序时无法使用到索引时,就会出现这个。常见于order by和group by语句中(这是可能是ordery by,group by语句的结果,这可能是一个CPU密集型的过程,可以通过选择合适的索引来改进性能,用索引来为查询结果排序)
Using index查询时不需要回表查询,直接通过索引就可以获取查询的数据。,这发生在对表的全部的请求列都是同一个索引的部分的时候。 说明查询是覆盖了索引的,不需要读取数据文件,从索引树(索引文件)中即可获得信息。例如select id from tb_user where id = 1 ,id是主键
Using temporary看到这个的时候,查询需要优化了。表示使用了临时表存储中间结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上(常用于GROUP BY 和 ORDER BY操作中)。
using where表示MySQL将对存储引擎层提取的结果进行过滤,过滤条件字段无索引。例如:select * from test where age > 30; 所以,Using where本身其实和是否使用索引无关,它表示的是Server层对存储引擎层返回的数据所做的过滤。当然该过滤可能会回表,也可能不会回表,取决于查询字段是否被索引覆盖。
五、索引失效

1、违背最左原则
2、隐式转换导致索引失效,比如索引字段的类型是varchar,但是却使用了其他类型
select * form tb_test where id = 121;不使用
select * form tb_test where id = “121”;使用索引
3、对索引列进行运算导致索引失效,运算包括(+,-,*,/,! 等)
select * from test where id-1=9;不使用
select * from test where id=10;使用
4、使用 <> 、not in 、not exist、!=
5、like “%_” 百分号在前(可采用在建立索引时用reverse(columnName)这种方法处理)
6、字符型字段为数字时在where条件里不添加引号.
7、当变量采用的是times变量,而表的字段采用的是date变量时.或相反情况。
8、判断字段是否为空使用=或者!=,应该使用is null或者is not null
9、where中使用OR来连接条件,导致引擎放弃索引来执行全表扫描,可以使用UNION进行合并查询:select id from t where num = 30 union select id from t where num = 40;

Mysql联合索引的生效方式,最左前缀匹配 1. 我们先创建表 create table test( a int , b int, c int, d int, key index_abc(a,b,c) )engine=InnoDB default charset=utf8; 2. 插入一些数据 DROP PROCEDURE IF EXISTS proc_initData; DELIMITER $ CREATE PROCEDURE proc_initData() BEGIN DECLARE i INT DEFAULT 1; WHILE i& 阅读详情

相关推荐

基于Active-HDL的HDL设计录入与仿真

作者:毛茏玮 / Saint 掘金:https://juejin.im/user/5aa1f89b6fb9a028bb18966a 微博:https://weibo.com/5458277467/profile?topnav=1&amp;wvr=6&amp;is_all=1 GitHub:github.com/saint-000 优快云: https://me.youkuaiyun.com/qq_4053...

一个会写代码的烤鸭 7780

mysql如何优化联合索引abc使用

mysql 之前有讲述过关于索引的分类以及应用mysql索引应用本篇则主要是针对联合索引abc来进行实践操作说明。 大家想找employees数据包可以查看如上链接博客。 一、创建索引abc 那么acb,bac等查询条件索引生效吗? 创建一个联合索引abc 索引的type以及length如下: 1)key-len列的计算规则 2)sql执行 1>abc执行 explain select * from employees where uid=4 and first_name=“Cristine

不管风吹浪打,胜似闲庭信步 2285

Visual Studio Installer下载失败的5种修复方法(含DNS修改/补丁安装)

本文针对Visual Studio Installer下载安装文件失败的问题,提供了从网络层到系统层的深度排查与修复指南。详细介绍了DNS修改、代理配置、防火墙设置、系统服务检查等5种核心修复方法,并包含离线安装与手动补丁等替代方案,帮助开发者彻底解决安装难题。

sprite的博客 1610

【转】mysql索引(最左匹配原则)

关于mysql索引的基础知识和最左原则解释

helloworldouyang的博客 6007

实战指南:利用 LangGraph 的状态管理实现多轮对话的上下文隔离与持久化

本文详细介绍了如何利用LangGraph的状态管理机制,高效实现多轮对话中的上下文隔离与持久化。通过实战代码演示,从基础的消息历史管理到自定义状态扩展,再到使用SQLite进行生产级持久化,系统讲解了如何借助LangGraph的State和Checkpointer自动化处理对话记忆、用户隔离及数据存储,显著提升开发效率。

weixin_28396629的博客 488

✨使用 vLLM + Docker 部署 Qwen3-Embedding-8B 并实现高效文本向量生成(附 `curl` 测试)

本文介绍了如何使用 vLLM 和 Docker 部署 Qwen3-Embedding-8B 嵌入模型服务,并通过标准 OpenAI 兼容接口进行调用和结果解析。如果你在部署中遇到任何问题,欢迎留言讨论!

用大模型重构生活:猫奴程序员的AI智能日常记录 6236

mysql 联合索引 abc_ABC联合索引生效问题(整理笔记!!!)

版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明。本文链接:https://blog.youkuaiyun.com/qq_42630887/article/details/97113323对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是key index (a,b,c)。 可以支持a | a,...

weixin_40000131的博客 4458

手把手教你学Simulink——基于智能电网与AI融合的场景实例:强化学习在并网逆变器控制中的应用

本文介绍了如何利用Simulink和强化学习工具包实现并网逆变器的智能控制。针对传统PI控制方法的局限性,提出采用强化学习(RL)构建自适应控制系统。通过详细步骤展示了从建立主电路模型、设计强化学习环境、选择训练智能体(如PPO算法)到仿真对比测试的全过程。实验结果表明,RL控制器在动态响应、THD指标和参数鲁棒性等方面优于传统PI控制器,突显了数据驱动控制在复杂电力系统中的优势。文章还探讨了该技术在微电网协同控制、在线学习等场景的拓展应用,为智能电网控制提供了新思路。

MHD0815的博客 335

MySQL数据库:SQL语句与索引优化

本文系统介绍了MySQL数据库优化核心要点,重点剖析了SQL查询与索引优化策略。主要内容包括:1)MySQL基础CRUD操作;2)高级查询技巧(联表、子查询、分组统计);3)事务管理ACID特性和隔离级别;4)B+树索引原理及最左前缀匹配原则;5)实战慢查询优化方法,包括EXPLAIN分析、索引添加和覆盖索引应用。文章强调索引"恰到好处"原则,需权衡查询性能与写操作开销,通过持续优化构建高性能MySQL应用。

2503_93373937的博客 2369

[Dify实战] 项目复盘助手:自动拉数据、生成复盘报告

本文介绍如何利用Dify平台构建自动化项目复盘助手,解决传统人工复盘效率低、易遗漏等问题。系统通过自动拉取Git/Jira等数据源,计算关键指标后,由LLM生成结构化复盘报告。文章详细讲解了数据采集、指标计算、Prompt设计等核心模块的实现,并分享了完整Workflow搭建步骤。实践表明,该系统能将复盘耗时从4小时缩短至10分钟,显著提升数据准确率和执行频率。最后总结了数据一致性、输出质量等常见问题的解决方案,强调Dify+LLM组合可实现复盘流程的自动化流水线。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 117

【ROS机器人系统】自主导航+YOLO目标检测+语音播报

完成自主导航功能,并在小车移动至指定地点的过程中,通过机器人的摄像头检测导航途中所见物体,识别出物体的种类(框选出不同物体并标注识别结果),结合科大讯飞语音合成模块对识别结果进行语音播报。..............................

南京大学软件工程硕士在读 2万+

Python SQL 语句优化与数据库索引管理(MySQL、PostgreSQL)

通过本文的介绍,我们可以看到,无论是 Python 的 SQL 查询优化还是数据库索引管理,都需要开发者具备一定的专业知识和实践经验。正确的工具选择、合理的查询设计以及持续的性能监控都是成功的关键因素。希望这篇文章能为你提供一些有价值的参考,帮助你在实际项目中实现更高效的数据库操作!```

2501_90746500的博客 1364

LVGL v8学习笔记 | 09 - 进度条控件的使用方法(bar)

lv_bar_set_range必须放在lv_bar_set_mode前面,否则不生效。bar对象的API在lv_bar.h中声明,以lv_bar_xxx命名。此事件可以用来在进度条更新值之后更新别的控件(比如进度条旁边的文字)。可以看到,默认创建的进度条值是0到100。(3)设置进度条的范围值(最大值和最小值)(2)获取进度条的起始值。(3)获取进度条的最小值。(4)获取进度条的最大值。(1)设置进度条的当前值。(2)设置进度条的起始值。(1)获取进度条当前值。(5)获取进度条的模式。

Mculover666的博客(嵌入式) 1729

MySql数据库优化之SQL和索引的优化

索引的优化是面试中数据库部分可以说是必问的问题,这个和平时的积累有关。本文详细介绍了SQL和索引的优化。

李志杰的博客 3581

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

揭秘MySQL索引与SQL优化策略,让你的数据库飞起来!

你是否曾经遇到过数据库查询速度慢的问题?是否对如何优化SQL语句感到困惑?今天,我们将一起探索MySQL索引与SQL优化策略,帮助你解决这些问题。

Q2024107的博客 477

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Mysql数据库优化之SQL及索引优化

1. 如何发现有问题的SQL? 使用mysql慢查询日志对有效率问题的Sql进行监视 (1) show variables like 'slow_query_log'; 查看慢查询日志是否开启 (2) set global slow_qeury_log_file = '/home/mysql/sql_log/mysql_slow.log' 设置慢查询日志文件的位置...

693

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

MySQL数据库SQL优化案例(走错索引)

MySQL数据库SQL优化案例(走错索引)

chenoracle的博客 840

解析MySQL数据库:“SQL优化”与“索引优化”!

负向条件有:!=、<>、not in、not exists、not like 等例如下面SQL语句:(假设status的取值为0、1、2、3、4)范围条件有:<、<=、>、>=、between等。索引最多用于一个范围列,如果查询条件中有两个范围列则无法全用到索引。假如有联合索引 (emp_no 、title、from_date ),那么下面的 SQL 中 emp_no 可以用到索引,而title 和 from_date 则使用不到索引。

jcc4261的博客 1181

Java- MySql sql优化、索引、jdbc连接数据库

数据库优化 在进行程序编写以及程序运行时,往往需要进行大量的数据库操作,但是,随着数据量的增大,数据字段的增多,在进行sql查询时往往可能消耗大量的时间,并且获取数据后还需要将数据发送给用户,这样就造成了程序响应时间过长,为了提高客户体验,数据库优化就必须进行(提高效率) 数据库优化提高效率大致分为三类: 1、硬件优化 提高数据库软件服务器硬件性能 2、软件优化 通过配置conf下my.ini进行属性的配置进行优化 3、sql语句优化 (1)尽量少进行计算 Mysql的作用是用来存取数据的,不是做计算的,做

jiandanyou的博客 290

mysql oracle数据库索引分类_Oracle mysql 数据库建立索引及SQL优化

原标题:Oracle mysql 数据库建立索引及SQL优化数据库索引:索引有单列索引 和 复合索引之说如何某表的某个字段有主键约束和唯一性约束,则Oracle 则会自动在相应的约束列上建议唯一索引。数据库索引主要进行提高访问速度。建设原则:1、索引应该经常建在Where 子句经常用到的列上。如果某个大表经常使用某个字段进行查询,并且检索行数小于总表行数的5%。则应该考虑。2、对于两表连接的字段,...

weixin_39834149的博客 96

SQL语句优化、mysql不走索引的原因、数据库索引的设计原则

17)联合索引 is not null 只要在建立的索引列(不分先后)都会走, in null时 必须要和建立索引第一列一起使用,当建立索引第一位置条件是is null 时,其他建立索引的列可以是is null(但必须在所有列 都满足is null的时候),或者=一个值;如果索引字段的值很长,最好使用值的前缀来索引。5) 查询条件使用函数在索引列上,或者对索引列进行运算,运算包括(+,-,*,/,!为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索引。...

Laity 1181
上一篇: mysql数据库详解(二):mybatis与springboot整合
下一篇: mysql数据库详解(四):基础知识
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值