索引优化详解

MySQL 索引优化详解 当一个索引包含了查询所需的所有字段时,这个索引就被称为覆盖索引。在执行查询时,MySQL 可以直接从索引中获取结果,而不需要访问表数据。这不仅减少了 I/O 操作,还提高了查询效率。MySQL 索引优化是数据库性能优化的重要部分,通过合理使用索引、利用覆盖索引、以及掌握索引合并技术,可以显著提升查询性能。在设计索引时,既要考虑查询的频率和复杂度,也要兼顾写入性能的影响。在实际应用中,结合业务需求和查询模式,选择适当的索引优化策略,是提升 MySQL 数据库性能的关键。 阅读详情

一、EXPLAIN
做MySQL优化,我们要善用 EXPLAIN 查看SQL执行计划。
下面来个简单的示例,标注(1,2,3,4,5)我们要重点关注的数据
在这里插入图片描述

type列,连接类型。一个好的sql语句至少要达到range级别。杜绝出现all级别
key列,使用到的索引名。如果没有选择索引,值是NULL。可以采取强制索引方式
key_len列,索引长度
rows列,扫描行数。该值是个预估值
extra列,详细说明。注意常见的不太友好的值有:Using filesort, Using temporary

二、SQL语句中IN包含的值不应过多

MySQL对于IN做了相应的优化,即将IN中的常量全部存储在一个数组里面,而且这个数组是排好序的。但是如果数值较多,产生的消耗也是比较大的。再例如:select id from table_name where num in(1,2,3) 对于连续的数值,能用 between 就不要用 in 了;再或者使用连接来替换。

三、SELECT语句务必指明字段名称

SELECT *增加很多不必要的消耗(cpu、io、内存、网络带宽);增加了使用覆盖索引的可能性;当表结构发生改变时,前断也需要更新。所以要求直接在select后面接上字段名。

四、当只需要一条数据的时候,使用limit 1

这是为了使EXPLAIN中type列达到const类型

五、如果排序字段没有用到索引,就尽量少排序

六、如果限制条件中其他字段没有索引,尽量少用or

or两边的字段中,如果有一个不是索引字段,而其他条件也不是索引字段,会造成该查询不走索引的情况。很多时候使用 union all 或者是union(必要的时候)的方式来代替“or”会得到更好的效果

七、尽量用union all代替union

union和union all的差异主要是前者需要将结果集合并后再进行唯一性过滤操作,这就会涉及到排序,增加大量的CPU运算,加大资源消耗及延迟。当然,union all的前提条件是两个结果集没有重复数据。

八、不使用ORDER BY RAND()

select id from table_name
order by rand() limit 1000;
上面的sql语句,可优化为
select id from table_name t1 join
(select rand() * (select max(id) from table_name) as nid) t2
on t1.id > t2.nid limit 1000;

九、区分in和exists, not in和not exists

select * from 表A where id in (select id from 表B)

上面sql语句相当于

select * from 表A where exists
(select * from 表B where 表B.id=表A.id)

区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询。所以IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。

关于not in和not exists,推荐使用not exists,不仅仅是效率问题,not in可能存在逻辑问题。如何高效的写出一个替代not exists的sql语句?

原sql语句

select colname … from A表 
where a.id not in (select b.id from B表)

高效的sql语句

select colname … from A表 Left join B表 on 
where a.id = b.id where b.id is null

取出的结果集如下图表示,A表不在B表中的数据
在这里插入图片描述
十、使用合理的分页方式以提高分页的效率

select id,name from table_name limit 866613, 20

使用上述sql语句做分页的时候,可能有人会发现,随着表数据量的增加,直接使用limit分页查询会越来越慢。

优化的方法如下:可以取前一页的最大行数的id,然后根据这个最大的id来限制下一页的起点。比如此列中,上一页最大的id是866612。sql可以采用如下的写法:

select id,name from table_name where id> 866612 limit 20

十一、分段查询
在一些用户选择页面中,可能一些用户选择的时间范围过大,造成查询缓慢。主要的原因是扫描行数过多。这个时候可以通过程序,分段进行查询,循环遍历,将结果合并处理进行展示。

如下图这个sql语句,扫描的行数成百万级以上的时候就可以使用分段查询
在这里插入图片描述
十二、避免在 where 子句中对字段进行 null 值判断

对于null的判断会导致引擎放弃使用索引而进行全表扫描。

十三、不建议使用%前缀模糊查询

例如LIKE “%name”或者LIKE “%name%”,这种查询会导致索引失效而进行全表扫描。但是可以使用LIKE “name%”。

那如何查询%name%?

如下图所示,虽然给secret字段添加了索引,但在explain结果果并没有使用
在这里插入图片描述
那么如何解决这个问题呢,答案:使用全文索引

在我们查询中经常会用到select id,fnum,fdst from table_name where user_name like ‘%zhangsan%’;。这样的语句,普通索引是无法满足查询需求的。庆幸的是在MySQL中,有全文索引来帮助我们。

创建全文索引的sql语法是:

ALTER TABLE table_name ADD FULLTEXT INDEX idx_user_name (user_name);

使用全文索引的sql语句是:

select id,fnum,fdst from table_name
where match(user_name) against(‘zhangsan’ in boolean mode);

注意:在需要创建全文索引之前,请联系DBA确定能否创建。同时需要注意的是查询语句的写法与普通索引的区别

十四、避免在where子句中对字段进行表达式操作

比如

select user_id,user_project from table_name where age*2=36;

中对字段就行了算术运算,这会造成引擎放弃使用索引,建议改成

select user_id,user_project from table_name where age=36/2;

十五、避免隐式类型转换

where 子句中出现 column 字段的类型和传入的参数类型不一致的时候发生的类型转换,建议先确定where中的参数类型

十六、对于联合索引来说,要遵守最左前缀法则

举列来说索引含有字段id,name,school,可以直接用id字段,也可以id,name这样的顺序,但是name,school都无法使用这个索引。所以在创建联合索引的时候一定要注意索引字段顺序,常用的查询字段放在最前面

十七、必要时可以使用force index来强制查询走某个索引

有的时候MySQL优化器采取它认为合适的索引来检索sql语句,但是可能它所采用的索引并不是我们想要的。这时就可以采用force index来强制优化器使用我们制定的索引。

十八、注意范围查询语句

对于联合索引来说,如果存在范围查询,比如between,>,<等条件时,会造成后面的索引字段失效。

十九、关于JOIN优化
在这里插入图片描述

select * from A left join B on B.name = A.name
where B.name is null
union all
select * from B;

尽量使用inner join,避免left join

参与联合查询的表至少为2张表,一般都存在大小之分。如果连接方式是inner join,在没有其他过滤条件的情况下MySQL会自动选择小表作为驱动表,但是left join在驱动表的选择上遵循的是左边驱动右边的原则,即left join左边的表名为驱动表。

合理利用索引

被驱动表的索引字段作为on的限制字段。

利用小表去驱动大表

二十、count(1)、count(*)与count(列名)的执行区别

  1. count(1) and count(*)
当表的数据量大些时,对表作分析之后,使用count(1)还要比使用count(*)用时多了! 

从执行计划来看,count(1)和count(*)的效果是一样的。 但是在表做过分析之后,count(1)会比count(*)的用时少些(1w以内数据量),不过差不了多少。 

如果count(1)是聚索引,id,那肯定是count(1)快。但是差的很小的。 

因为count(*),自动会优化指定到那一个字段。所以没必要去count(1),用count(*),sql会帮你完成优化的 因此: count(1)和count(*)基本没有差别! 

  1. count(1) and count(字段)
两者的主要区别是

(1) count(1) 会统计表中的所有的记录数, 包含字段为null 的记录。

(2) count(字段) 会统计该字段在表中出现的次数,忽略字段为null 的情况。即 不统计字段为null 的记录。  

count(*) 和 count(1)和count(列名)区别  

执行效果上 :  

count(*)包括了所有的列,相当于行数,在统计结果的时候, 不会忽略列值为NULL  
 count(1)包括了忽略所有列,用1代表代码行,在统计结果的时候, 不会忽略列值为NULL  
 count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是只空字符串或者0,而是表示null)的计数, 即某个字段值为NULL时,不统计。

执行效率上:   
列名为主键,count(列名)会比count(1)快   
列名不为主键,count(1)会比count(列名)快   
如果表多个列并且没有主键,则 count(1) 的执行效率优于 count(*)   
如果有主键,则 select count(主键)的执行效率是最优的   
如果表只有一个字段,则 select count(*)最优。
详解 MongoDB 索引优化 索引通常能够极大的提高查询的效率,如果没有索引,MongoDB 在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。 阅读详情

相关推荐

【MySql】索引下推优化详解、常见sql深入优化

order by语句使用索引最左前列。使用where子句与order by子句条件列组合满足索引最左前列。3、尽量在索引列上完成排序,遵循索引建立(索引创建的顺序)时的最左前缀法则。4、如果order by的条件不在索引列上,就会产生Using filesort。5、能用覆盖索引尽量用覆盖索引6、group by与order by很类似,其实质是先排序后分组,遵照索引创建顺序的最左前缀法则。对于group by的优化如果不需要排序的可以加上order by null禁止排序。

这个人很懒什么都没有留下 1060

MySQL索引优化(超详细)

MySQL索引优化,涉及到索引介绍,性能分析,查询优化,慢查询日志。

weixin_55816781的博客 9379

AI数字人:口播与唇形同步的福音,支持本地部署/批量生成/口齿清晰

你也可以直接输入语音,虚拟化身会根据语音的节奏和语调,同步做出相应的动作和表情,表现更加生动。不过这依然是个值得关注的工具。借助先进的 AI 算法,Heygem 高精度捕捉五官、轮廓等特征,构建逼真的虚拟模型。同时,它还能克隆语音,捕捉人声的细微特征,支持多种语音参数设置,打造高度相似的音色效果。打开设置,调整镜像存储位置,镜像文件比较大70~80G,选择合适的盘,设置完成后点击“Apply & Restart”。数字人视频画面与声音高度同步,口型匹配自然流畅,智能优化音视频效果,带来极佳的视听体验。

m0_72580657的博客 5860

一文带你你搞懂索引如何优化!!!

前言索引的相信大家都听说过,但是真正会用的又有几人?平时工作中写SQL真的会考虑到这条SQL如何能够用上索引,如何能够提升执行效率?此篇文章详细的讲述了索引优化的几个原则,只要在工作中能...

码猿技术专栏 4172

智能优化电池:基于单片机的电池管理系统

设计简介: 本设计是基于单片机的电池管理系统,主要实现以下功能: 可通过LCD1602显示温度、电压电流值; 可通过按键调整温度、电压和电流的阈值; 用ADC0832将模拟量转换为数字量。 标签:51单片机、LCD1602、ADC0832 效果图: 总体资料: 原理图: 软件设计流程: 系统框图: 本设计以STC89C52单片机为核心控制器,加上其他的模块一起组成电动汽车的电池管理的整个系统,...

专注单片机实战教学,分享单片机学习资料 375

aruco_ros实战:从USB摄像头到Marker位姿检测全流程解析

本文详细解析了使用aruco_ros从USB摄像头实现ArUco Marker检测与位姿估计的全流程。内容涵盖环境搭建、核心launch文件配置、可视化调试、位姿数据解析以及深度优化技巧,帮助开发者快速掌握ROS下的视觉定位关键技术,并集成到机器人项目中。

weixin_29230805的博客 263

优化索引的方法

为了避免索引隐式转换带来的性能问题,在编写 SQL 查询时,应注意查询条件中数据类型的匹配,尽量进行显式的类型转换,确保与字段的数据类型一致。由于索引通常需要在内存和磁盘中进行存储和处理,较小的索引字段大小意味着在一个索引页中能够容纳更多的索引值,从而提高索引的查询速度。联合索引按照字段在索引中的定义顺序进行匹配,如果查询条件的字段顺序与联合索引的顺序不一致,可能无法充分利用索引的优势。例如,对于一个包含很长字符串描述的字段,如文章的内容摘要,如果直接对整个字符串创建索引,会占用大量的空间。

lu_la_la_的博客 4132

最短线性递推式求解与有理函数重建

这一算法来自于我们对“线性递推式拟合”的视角转换,其后得到的算法是自然的。 引理 1. 如果两个有理分式 p1/q1,p2/q2p_1/q_1, p_2/q_2p1​/q1​,p2​/q2​ 均有 deg⁡p<n,deg⁡q≤n\deg p<n, \deg q\leq ndegp<n,degq≤n 且展开式 p1/q1≡p2/q2(modx2n)p_1/q_1 \equiv p_2/q_2 \pmod {x^{2n}}p1​/q1​≡p2​/q2​(modx2n),那么 p1/q1=p2/

Entropy Increaser 的博客 2589

项目中常用的MySQL优化你知道多少?

项目中常用的MySQL优化 文章目录项目中常用的MySQL优化前言一、mysql优化是什么?二、优化步骤1.EXPLAIN2.SQL语句中IN包含的值不应过3.SELECT语句务必指明字段名称4.如果排序字段没有用到索引,就尽量少排序5.如果限制条件中其他字段没有索引,尽量少用or6.尽量用union all代替union7.不使用ORDER BY RAND()8.区分in和exists, not in和not exists9.使用合理的分页方式以提高分页的效率10.分段查询11.不建议使用%前缀模糊查询1

qq_40500045的博客 1650

lgv20刷twrp_LG港版v20 root

这是LG港版v20 root,整理了一下有关LG港版v20的官方固件包了,有没有需要的呢,这里把固件包整理一下也是方便大家以后好下载了,因此有一些机友还是不知道在哪里下载官方的rom包,在这里说的固件rom包也就是原版的系统包了,大家可以放心的使用,这些系统包也都是支持线刷的,大家下载下来解压出来根据里面的相关教程来操作就可以了,很简单的,如果你也需要的话就一起来看看吧。软件提示注意!! 此过程会...

weixin_33212263的博客 5387

Python 爬虫实战:全面解析雪球网用户投资组合数据采集

本文介绍了如何使用 Python 爬虫技术,抓取雪球网用户的投资组合信息。通过模拟登录、解析页面内容等步骤,获取了用户的持仓数据。未来,可以进一步探索以下方向:

2201_76125261的博客 1303

【索引优化一详解】

联合索引首个字段使用范围查询通常不会走索引,因MySQL认为回表效率低 强制走索引可能不如全表扫描高效 覆盖索引可避免回表,显著提升性能 in/or在数据量大时会走索引,小表时倾向全表扫描 like 'KK%'多走索引,涉及索引下推优化 对于排序优化: 遵循最左前缀原则,避免跳过中间字段导致filesort 正确顺序的字段组合排序可避免filesort 索引下推在5.6+版本可减少回表次数

liwenhua的博客 1007

Unity 如何使用命令模式

命令模式 游戏中,当你想通过一种通用的方式来存储命令并能够撤消命令时,那么命令模式最有用。 在“示例”中,你将看到一个可以通过GUI按钮移动的简单点。 采取行动后,您可以撤消并重做。我在屏幕上添加了一个简单的OnGUI标签输出,因此您可以看到命令列表,并指出哪个是当前命令。 在此示例中使用了4个类: Command-这是任何命令模式都可以继承的基本结构(抽象类)。您可以在任何项目中使用此类。 MoveCommand-这是从Command类继承的结构,将使用Execute和UnExecute(撤消)。每个移

TxNet 1553

MYSQL 索引详解及索引优化、分析

索引在MySQL中是比较常见的,索引就相当于我们看书的目录,它是帮助MySQL高效获取数据的一种数据结构,主要用来提高数据的检索效率,减少IO成本,同时通过索引对数据进行排序,降低排序成本。2.索引的作用加快查询速度:通过索引快速定位数据。保证数据唯一性:如主键和唯一索引。优化排序和分组:索引可以加速ORDER BY和GROUP BY操作。用二级索引查数据时,会先检二级索引中的 B+Tree 的索引值(商品编码,product_no),找到对应的叶子节点,然后获取主键值,然后再通过主键索引。

2201_75656709的博客 1860

【Power Compiler手册】13.UPF多电压设计实现(2)

在这个场景中,在约束传播期间,工具会比较BLOCK中的原子电源域与TOP设计中的原子电源域,并且确认所有属性都匹配。因此,域合并成功,工具会丢弃来自BLOCK的域。在这个场景中,在约束传播期间,工具会比较BLOCK中的原子电源域与TOP设计中的非原子电源域,发现电源域不匹配。在这个场景中,在约束传播期间,工具会比较BLOCK中的非原子电源域与TOP设计中的原子电源域,发现电源域不匹配。在这个场景中,在约束传播期间,工具会比较BLOCK中的原子电源域与TOP设计中的原子电源域,发现它们的一些属性不匹配。

QRBQ 750

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

MySql索引优化详解

关于存储引擎的区别可见 Innodb跟Myisam的区别一般索引数据结构有以下几种: 二叉树、红黑树、Hash树、B-Tree。 二叉树、红黑树: Hash树: 对索引的key进行一次hash运算就可以定位出数据存储的位置。 很多时候Hash索引要比B+树索引更高效。 仅能满足 “=” 、“IN” ,不支持范围查询。 有hash冲突问题。 B-Tree: 叶节点具有相同的深度,叶节点的指针为空。 所有索引元素不重复。 节点中的数据索引从做到右递增排列。 Mysql一般采用B+树(B-tree变种): 非叶

weixin_42223521的博客 418

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Mysql详解——索引优化

本篇文章是对Mysql索引的创建以及优化进行一个介绍,关于索引的底层原理可以看我另一篇文章:Mysql详解——索引详解 文章目录一、索引的创建和设计原则1. 索引的声明和使用1.1 索引的分类:1.2 索引的创建:在创建表时创建索引:在已经存在的表上创建索引:1.3 索引的删除:2. MySQL8.0中索引新特性2.1 支持降序索引2.2 支持隐藏索引3. 索引的设计原则3.1 数据准备:3.2 哪些情况适合创建索引1. 字段值有唯一性的限制2. 频繁作为WHERE查询条件的字段3. 经常GROUP BY和

OYMNCHR的博客 4304

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

MySQL索引详解与优化策略

MySQL的索引是在存储引擎层实现的,不同的存储引擎支持的索引类型并不完全相同。例如,常见的InnoDB存储引擎支持B-tree索引,而Memory存储引擎则支持Hash索引。

m0_73355421的博客 1328

Explain详解与索引优化

使用EXPLAIN可以分析查询语句用法表的读取顺序数据读取操作的操作类型哪些索引可以使用哪些索引被实际使用表之间的引用每张表有多少行被优化器查询。

weixin_44275670的博客 1580

【MySQL】Explain详解与索引优化实战

目录 1、使用的表 2、explain 中的列 2.1 id列 1)简单子查询 2)from子句中的子查询 3)union查询 2.2 select_type列 2.3 table列 2.4 type列 2.5 possible_keys列 2.6 key列 2.7 key_len列 2.8 ref列 2.9 rows列 2.10 Extra列 3、索引优化实战 ...

小七的博客 1486

详解索引及优化

创建索引可以大大提高系统的性能。通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。可以大大加快数据的检索速度,这也是创建索引的最主要的原因。可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。也许会有人要问:增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?这种想法固然有其合理性,然而也有其片面性。

yjl33的专栏 840

MySQL性能调优——索引详解与索引的优化

——索引优化,可以说是数据库相关优化、理解尤其是查询优化中最常用的优化手段之一。所以,只有深入索引的实现原理、存储方式、不同索引间区别,才能设计或使用最优的索引,最大幅度的提升查询效率! 一、BTree索引 1、概述 Mysql数据库中使用最频繁的索引类型,基本所有存储引擎都支持BTree索引。正是其优异的检索表现,才使其有这样的地位。 2、存储结构 正如其名,这类索引的物理文件

Leeon的博客 3万+

二、Explain详解与索引优化最佳实践

=使用EXPLAIN关键字可以模拟优化器执行SQL语句,分析你的查询语句或是结构的性能瓶颈 ==在 select 语句之前增加 explain 关键字,MySQL 会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是执行这条SQL注意:如果 from 中包含子查询,仍会执行该子查询,将结果放入临时表中。

蓝天it(让亿万孩子在蓝天下共享优质教育) 1064

SqlServer索引及优化详解

比如,我们要查“安”字,就会很自然地翻开字典的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字母“a”开头并以“z”结尾的,那么“安”字就自然地排在字典的前部。比如您的某个表有一个时间列,恰好您把聚合索引建立在了该列,这时您查询2004年1月1日至2004年10月1日之间的全部数据时,这个速度就将是很快的,因为您的这本字典正文是按日期进行排序的,聚类索引只需要找到要检索的所有数据中的开头和结尾数据即可;所以笔者刚开始使用这个存储过程时,感觉非常的不错,速度也比原来的ADO的好。

weixin_42164754的博客 975

【MySql索引优化二详解】

文章主要探讨了MySQL中的索引优化策略,特别是分页查询和表关联查询的优化技巧。对于分页查询,若主键自增且连续,可以通过改写SQL语句减少扫描行数;若基于非主键字段排序,建议先查询主键再获取记录,以提高效率。在表关联查询中,MySQL常用Nested-Loop Join(NLJ)和Block Nested-Loop Join(BNL)两种算法。NLJ适用于被驱动表关联字段有索引的情况,而BNL则用于无索引场景,通过将驱动表数据加载到内存中减少磁盘I/O,尽管可能增加内存判断次数。优化策略强调根据实际情况选择

liwenhua的博客 875

索引优化示例详解

单表索引优化创建一张article表CREATE TABLE IF NOT EXISTS `article`( `id` INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT, `author_id` INT(10) UNSIGNED NOT NULL, `category_id` INT(10) UNSIGNED NOT NULL, `views

charming的专栏 1765
上一篇: 索引概念详解
下一篇: b树与b+树的原理介绍
百里度
博客等级 码龄12年 26粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值