MySQL索引及SQL优化

news2024/12/27 11:43:56

先对索引做个大概回顾,然后我们详细探讨SQL优化

索引

索引的分类

主键索引

设定为主键后数据库会自动建立索引,innodb为聚簇索引

单值索引

即一个索引只包含单个列,一个表可以有多个单列索引【建议不要超过3】

唯一索引

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

复合索引

又称之为 组合索引、联合索引即一个索引包含多个列

最左原则(此原则只针对:复合索引)

(工号、名称、入职日期) 作为一个组合索引,将会生成的索引目录结构。由接口可以看出,工号是最先需要判断的字段,所以工号这个查询条件必须存在工号判断完,才会判断名称名称判断完才会判断入职日期

也就是说,组合索引查询条件必须得带有最左边的列:对于我们的索引:

  • 条件为: (工号,名称,入职日期) 这几种情况都是生效的
  • 条件为: (名称)不生效 (名称,入职日期)不生效
  • 条件为 (工号) (工号,名称)(工号,入职日期)部分生效
  • 条件为 (工号,名称,入职日期)全部生效

索引优缺点

索引的优点

  • 建立索引的列可以保证行的唯一性,生成唯一的rowId
  • 建立索引可以有效缩短数据的检索时间==【合理的建立索引】合理:user_code 不合理:user_sex ,全部字段都添加索引,数据量过小==
  • 建立索引可以加快表与表之间的连接查询 select * from oeder o left join user u on u.id = o.user_id where o.id="1010011"
  • 为用来排序或者是分组的字段添加索引可以加快分组和排序速度

索引的缺点

  • 创建索引和维护索引需要时间成本,这个成本随着数据量的增加而加大
  • 创建索引和维护索引需要空间成本,每一条索引都要占据数据库的物理存储空间,数据量越大,占用空间也越大(数据表占据的是数据库的数据空间)
  • 会降低表的增删改的效率,因为每次增删改索引需要进行动态维护,导致时间变长

索引的选择

那些情况下需要创建索引

  • 主键自动建立唯一索引,【自增、UUID、雪花算法】
  • 频繁作为查询条件内容差异化大的字段应该创建索引【where 后面的语句】
  • 查询中与其它表关联的字段,外键关系建立索引【on条件的字段】
  • 单键/组合索引的选择问题,who?【在高并发下倾向创建组合索引
  • 查询中分组、排序的字段,排序字段若通过索引去访问将大大提高排序速度【order by 字段 group by 字段】
  • 查询中统计字段 sum(字段)

哪些情况不要创建索引

  • 记录比较少,本身数据就少即使加上索引也不会有太大的提升,增删改时还需要对索引维护进行维护,反而增加了工作量
  • where条件里用不到的字段不建立索引,选择索引的时候不是越多越好【单表少于3个索引】
  • 经常增删改的表,索引提高了查询的速度,同时却会降低更新表的速度,因为建立索引后, 如果对表进行INSERT,UPDATE 和DELETE, MYSQL不仅要保存数据,还要保存一下索引文件
  • 数据重复的表字段如果某个数据列包含了许多重复的内容,为它建立索引 就没有太大在的实际效果,比如表中的某一个字段为国籍,性别,数据的差异率不高,这种建立索引就没有太多意义。

SQL优化

为什么要SQL优化

在应用开发的过程中,由于前期数据量少,开发人员编写的SQL语句或者数据库整体解决方案都更重视在功能上的实现, 但是当应用系统正式上线后,随着生成数据量的急剧增长,很多SQL语句和数据库整体方案开始逐渐显露出了性 能问题,对生成的影响也越来越大,此时Mysql数据库的性能问题成为系统应用的瓶颈,因此需要进行Mysql数据库的性能优化。

性能下降的表现:

  1. 慢查询造成页面无法加载
  2. 阻塞造成数据无法提交

性能下降的原因:

  • 查询语句写的不好,各种连接,各种子查询导致用不上索引或者没有建立索引,胡乱建立索引
    • 【1、不常用字段 2、内容差别不大的数据字 3、单表索引字段超过3个】
  • 建立的索引失效,建立了索引,在真正执行时,没有用上建立的索引
  • select * from order 
    select id,name.age from order

  • 关联查询太多join
    select id form ordero left join user u on o.user_id = u.id left join user_Info ui on ui.user_id = u.id where u.age >18 and ui.school ='人民大学'

    wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

  • 服务器调优及配置参数导致,如果设置的不合理,比例不恰当,也会导致性能下降,sql变慢
  • 系统架构的问题

通用数据库优化

SQL及索引优化

  • 根据需求写出良好的SQL,并创建有效的索引,实现某一种需求可以多种写法,我们就要选择一种效率最高的写法,这个时候就要了解sql优化。【explain】
  • sql优化的目的之一就是==减少中间结果集==,降低物理IO

数据库表结构优化

  • 根据数据库的范式,设计表结构,表结构设计的好坏直接关系到SQL语句的复杂度。order ==>userName ==>userId==>user ===>userName
  • 适当的将表进行拆分,原本需要join的查询只需要一张单表查询就可以了。
  • 合理的分库、分表

系统配置优化

内核优化:linux 基础之-高并发内核优化_王道长的编程之路的博客-CSDN博客

  • 大多数运行在Linux机器上,如tcp连接数的限制、打开文件数的限制、安全性的限制,因此我们要对这些配置进行相应的优化

硬件优化

  • 数据库主机的IO性能是需要最优先考虑的一个因素
  • 数据库主机和普通的应用程序服务器相比,资源要相对集中很多,单台主机上所需要进行的计算量自然也就比较多,所以数据库主机的CPU处理能力也是一个重要的因素。
  • 数据库主机网络设备(一般指网卡等)的性能也可能会成为系统的瓶颈。

插入数据

如果我们需要一次性往数据库表中插入多条记录,可以从以下三个方面进行优化。

insert

优化方案一

批量插入数据

Insert into tb_test values(1,'Tom'),(2,'Cat'),(3,'Jerry');

优化方案二

手动控制事务

start transaction;
insert into tb_test values(1,'Tom'),(2,'Cat'),(3,'Jerry');
insert into tb_test values(4,'Tom'),(5,'Cat'),(6,'Jerry');
insert into tb_test values(7,'Tom'),(8,'Cat'),(9,'Jerry');
commit;

优化方案三

主键顺序插入,性能要高于乱序插入。

大批量插入数据

如果一次性需要插入大批量数据(比如: 几百万的记录),使用insert语句插入性能较低,此时可以使 用MySQL数据库提供的load指令进行插入。操作如下:

可以执行如下指令,将数据脚本文件中的数据加载到表结构中:

-- 客户端连接服务端时,加上参数 -–local-infile
mysql –-local-infile -u root -p

-- 设置全局参数local_infile为1,开启从本地加载文件导入数据的开关
set global local_infile = 1;

-- 执行load指令将准备好的数据,加载到表结构中
load data local infile '/root/sql1.log' into table tb_user fields terminated by ',' lines terminated by '\n' ;

主键顺序插入性能高于乱序插入

主键优化

为什么主键顺序插入的性能是要高于乱序插入的 ?

数据组织方式

在InnoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表行数据,都是存储在聚集索引的叶子节点上的。而我们之前也讲解过InnoDB的逻辑结构图:

在InnoDB引擎中,数据行是记录在逻辑结构 page 页中的,而每一个页的大小是固定的,默认16K。 那也就意味着, 一个页中所存储的行也是有限的,如果插入的数据行row在该页存储不小,将会存储 到下一个页中,页与页之间会通过指针连接。

页分裂

页可以为空,也可以填充一半,也可以填充100%。每个页包含了2-N行数据(如果一行数据过大,会行溢出),根据主键排列。

主键乱序插入可能会产生页分裂!

页合并

当页中删除的记录达到 MERGE_THRESHOLD(默认为页的50%),InnoDB会开始寻找最靠近的页(前 或后)看看是否可以将两个页合并以优化空间使用。

order by优化

MySQL的排序,有两种方式:

Using filesort : 通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sort buffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫 FileSort 排序。

Using index : 通过有序索引顺序扫描直接返回有序数据,这种情况即为 using index,不需要 额外排序,操作效率高。

对于以上的两种排序方式,Using index的性能高,而Using filesort的性能低,我们在优化排序操作时,尽量要优化为 Using index。

group by优化

在分组操作中,我们需要通过以下两点进行优化,以提升性能:

A. 在分组操作时,可以通过索引来提高效率。

B. 分组操作时,索引的使用也是满足最左前缀法则的。

limit优化

分页查询时,如果执行 limit 2000000,10 ,此时需要MySQL排序前2000010 记 录,仅仅返回 2000000 - 2000010 的记录,其他记录丢弃,查询排序的代价非常大 。

优化思路: 一般分页查询时,通过创建覆盖索引能够比较好地提高性能,可以通过覆盖索引加子查询形式进行优化。

select * from tb_sku t , (select id from tb_sku order by id
limit 2000000,10) a where t.id = a.id;

count优化

  • MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) 的时候会直接返回这个 数,效率很高; 但是如果是带条件的count,MyISAM也慢。
  • InnoDB 引擎就麻烦了,它执行 count(*) 的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数。

如果说要大幅度提升InnoDB表的count效率,主要的优化思路:自己计数(可以借助于redis这样的数 据库进行,但是如果是带条件的count又比较麻烦了)。

count用法

count() 是一个聚合函数,对于返回的结果集,一行行地判断,如果 count 函数的参数不是 NULL,累计值就加 1,否则不加,最后返回累计值。

用法:count(*)、count(主键)、count(字段)、count(数字)

按照效率排序的话,count(字段) < count(主键 id) < count(1) ≈ count(*),所以尽量使用 count(*)。

update优化

我们主要需要注意一下update语句执行时的注意事项。

update course set name = 'javaEE' where id = 1 ;

当我们在执行删除的SQL语句时,会锁定id为1这一行的数据,然后事务提交之后,行锁释放。

但是当我们在执行如下SQL时。

update course set name = 'SpringBoot' where name = 'PHP' ;

当我们开启多个事务,在执行上述的SQL时,我们发现行锁升级为了表锁。 导致该update语句的性能 大大降低。

InnoDB的行锁是针对索引加的锁,不是针对记录加的锁 ,并且该索引不能失效,否则会从行锁升级为表锁 。

总结

插入数据

insert:批量插入/手动控制事务/主键顺序插入

大批量插入:load data local infile

主键优化

主键长度尽量短/顺序插入

order by优化

using index:直接通过索引返回数据,性能高

using filesort:需要将返回的结果在排序缓冲区排序

group by优化

最好走索引,多字段分组满足最左前缀法则

limit优化

覆盖索引+子查询

count优化

性能:count(字段) < count(主键 id) < count(1) ≈ count(*)

uodate优化

尽量根据主键/索引字段进行数据更新

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

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

相关文章

算法训练第五十九天 | 503.下一个更大元素II 、42. 接雨水

单调栈part02503.下一个更大元素II题目描述思路42. 接雨水题目描述思路暴力解法双指针优化单调栈解法准备工作单调栈处理逻辑503.下一个更大元素II 题目链接&#xff1a;503.下一个更大元素II 参考&#xff1a;https://programmercarl.com/0503.%E4%B8%8B%E4%B8%80%E4%B8%AA%E…

升级长江存储最新闪存,忆恒创源发布新一代企业级NVMe SSD

2023年4月11日 —— 北京忆恒创源科技股份有限公司&#xff08;Memblaze&#xff09;正式发布搭载高品质国产闪存的PBlaze6 6541 系列企业级PCIe 4.0 NVMe SSD。作为 MUFP 平台化开发的最新作品&#xff0c;PBlaze6 6541 采用长江存储最新一代晶栈 Xtacking 3D NAND&#xff0c…

类中的那点事

c入门必看类类的基本介绍类的实例化类的6个默认成员函数构造函数析构函数拷贝构造函数赋值重载静态成员友元类 类的基本介绍 class为定义类的关键字&#xff0c;ClassName为类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后面分号不能省略。类体中内容称为类…

恢复删除的文件,小白也能轻松掌握的5个方法!

案例&#xff1a;如何恢复删除的文件&#xff1f; 【各位大神&#xff01;谁能帮帮我呀&#xff01;一不小心把电脑里很重要的文件删除了&#xff0c;不知道该如何是好&#xff0c;求一个简单方法&#xff0c;感谢大家&#xff01;】 在计算机使用过程中&#xff0c;误删文件…

Tomcat处理请求的全过程

文章目录一、组件详解二、请求处理流程1.总体流程图2.Worker线程任务流程三、源码跟踪1.Tomcat启动线程组件2.Acceptor3.Poller4.Worker总结一、组件详解 在Tomcat处理客户端请求的过程中&#xff0c;这里面有三个组件概念&#xff0c;他们都是线程&#xff0c;分别负责不同的…

NEWS|关于人工智能大型语言模型能否理解的争论

科学家调查了当前人工智能&#xff08;AI&#xff09;研究界的一场激烈的争论&#xff0c;即大型预先训练的语言模型是否可以说可以理解语言——以及任何类人意义上的语言编码的物理和社会情境。他们提供了支持和反对这种理解的论点&#xff0c;以及根据这些论点而出现的更广泛…

7个最新的时间序列分析库介绍和代码示例

时间序列分析包括检查随着时间推移收集的数据点&#xff0c;目的是确定可以为未来预测提供信息的模式和趋势。我们已经介绍过很多个时间序列分析库了&#xff0c;但是随着时间推移&#xff0c;新的库和更新也在不断的出现&#xff0c;所以本文将分享8个目前比较常用的&#xff…

SpringCloud学习(六)——Feign的简单使用

文章目录1. Feign 的使用1.1 引入依赖1.2 添加注解1.3 编写Feign客户端1.4 测试2. Feign中的自定义配置2.1.配置文件方式2.2.Java代码方式3. Feign 性能优化4. Feign的抽取式使用4.1 抽取配置4.2 引入依赖4.3 指明Client在此之前&#xff0c;我们服务之间需要进行调用的时候使用…

Spring Cloud Alibaba全家桶(十)——微服务网关Gateway组件

前言 本文小新为大家带来 微服务网关Gateway组件 相关知识&#xff0c;具体内容包括微服务网关Gateway组件&#xff08;包括&#xff1a;Gateway核心概念&#xff0c;Gateway工作原理&#xff09;&#xff0c;Spring Cloud Gateway环境搭建&#xff0c;路由断言工厂&#xff08…

颜值即正义,献礼就业季,打造多颜色多字体双飞翼布局技术简历模版(Resume)

一年好景君须记&#xff0c;最是橙黄橘绿时。金三银四&#xff0c;秣马厉兵&#xff0c;没有一个好看的简历模板怎么行&#xff1f;无论是网上随便下载还是花钱买&#xff0c;都是一律千篇的老式模版&#xff0c;平平无奇&#xff0c;味同嚼蜡&#xff0c;没错&#xff0c;蜡都…

一文理解Transformer整套流程

【备注】部分图片引至他人博客&#xff0c;详情关注参考链接 【PS】query 、 key & value 的概念其实来源于推荐系统。基本原理是&#xff1a;给定一个 query&#xff0c;计算query 与 key 的相关性&#xff0c;然后根据query 与 key 的相关性去找到最合适的 value。举个例…

mysql语法大全

首先来一个全局总览&#xff0c;后面我会分别对每个命令进行说明&#xff1a; 如果你的mysql导入环境变量&#xff0c;可以在命令行输入&#xff1a; mysql -u root -p然后输入密码登录数据库 否则&#xff0c;打开mysql command line并输入密码进入数据库 一&#xff0c;基础…

HTTP HTTPS简介

一篇文章带你走进HTTP HTTPS场景复现核心干货HTTP/HTTPS简介&#xff08;简单比较&#xff09;HTTP工作原理HTTPS作用场景复现 最近在对前端的深入学习过程中&#xff0c;接触到了与网络请求相关的内容&#xff0c;于是打算出一个专栏&#xff0c;从HTTP与HTTPS入手&#xff0…

针对航空安全风险分析和飞行技术评估问题的题解

文章目录针对航空安全风险分析和飞行技术评估问题的题解思路文章最下方针对航空安全风险分析和飞行技术评估问题的题解 最新进度在文章最下方卡片&#xff0c;加入获取思路数据代码论文&#xff1a;2023十三届MathorCup交流 (第一时间在CSDN分享&#xff0c;文章底部) 思路 问…

VFP读写t5557卡示例源码

T5557卡是美国Atmel公司生产的多功能非接触式射频卡芯片&#xff0c;属于125KHz的低频卡&#xff0c;在国内有广大的应用市场。该芯片共有330bit(比特)的EPROM(分布为10个区块, 每个区块33bit)。0页的块0是被保留用于设置T5557操作模式的参数配置块。第0页第7块可以作用户数据块…

Excel表格怎么换行?4个方法任你选!

案例&#xff1a;excel表格怎么换行 【作为一名excel新手&#xff0c;我真的要被各种功能整懵了&#xff01;今天又遇到了一个难题&#xff01;excel表格怎么换行呀&#xff1f;各位大神帮帮我&#xff01;】 在excel表格中进行换行操作是一种常见的需求&#xff0c;可以使单…

三分天下、格局初定,AR产业千亿市场谁执牛耳?

文|智能相对论 作者| 青月 【这是聚焦智能车与家的“智能相对论”关于创新硬件赛道的第27篇行业分析。】 早在十一年前&#xff0c;谷歌就推出了第一款AR眼镜Google Glass。 可由于当时1500美元的高昂价格&#xff0c;以及并不令人惊艳的体验&#xff0c;这款产品并未俘获消…

Flink1.14 Standalone独立集群模式安装

一、下载 在Flink 官网下载Flink 1.14&#xff0c;完整的安装包名是&#xff1a;flink-1.14.4-bin-scala_2.11.tgz。 二、master 配置 解压安装包&#xff0c;编辑conf/flink-conf.yaml文件&#xff1a; vim conf/flink-conf.yaml jobmanager.rpc.address: 172.21.0.XX tas…

N9010B频谱分析仪

N9010B N9010B EXA 信号分析仪&#xff0c;多点触控&#xff0c;10 Hz 至 44 GHz EXA X系列信号分析仪&#xff0c;多点触摸N9010B 本配置指南将帮助您确定哪些性能选项、测量应用程序、附件和服务将包含在新的多点触摸EXA中&#xff0c;或作为现有EXA的升级添加。主要特性和…

SSM实战-外卖项目-06-用户地址簿功能、菜品展示、购物车、下单

文章目录外卖项目-第六天课程内容1. 用户地址簿功能1.1 需求分析1.2 数据模型1.3 导入功能代码1.4 功能测试 &#xff08;其实需求分析里我就自己写了一份代码&#xff0c;而且测试过了&#xff0c;下面再测试了一遍&#xff09;2. 菜品展示2.1 需求分析2.2 前端页面分析2.3 代…