数据库--进阶版-11--SQL优化

1.插入数据

·insert优化:

例如要插入下面这些

insert into tb_test values(1,'tom');

insert into tb_test values(2,'cat');

insert into tb_test values(3,'jerry');

我们可以通过以下几个方面进行操作:

>批量插入(如果一次性要插入多条数据可以通过一条insert语句来完成)

像上面这样每次insert都要与数据库进行连接进行网络传输,这样性能相对是比较低的,所以可以考虑用批量插入。

insert into tb_test values(1,'tom'),(2,'cat'),(3,'jerry');

不过不能超过一千条,如果要一次插入一万条数据怎么办?可以可以分割为多条insert语句插入嘛

>手动提交事务

MySQL中事务提交方式默认是自动的,也就是说,当你执行完一条SQL语句后,它事务就提交了,再次执行一条insert,执行之前开启事务,执行完毕又关闭事务,这时候就涉及事务的频繁开启与提交,所以我们建议手动提交事务。

在insert之前开启事务,然后执行完多条SQL语句后再统一提交事务

例:

start transaction;

insert into tb_test values(1,'tom'),(2,'cat'),(3,'jerry');

insert into tb_test values(4,'tom1'),(5,'cat1'),(6,'jerry1');

insert into tb_test values(7,'tom2'),(8,'cat2'),(9,'jerry2');

commit;

>主键顺序插入

主键插入要么乱序插入要么顺序插入,建议主键顺序插入,因为顺序插入性能高于乱序插入。

·大批量插入数据

如果一次性需要插入大批量数据,比如要一次性将一百万的数据加载进表结构中,使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令进行插入。

需要做3步操作:

#客户端连接服务器端时,加上参数--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';

在执行load指令时我们也建议按照主键顺序插入,主键顺序插入性能高于乱序插入。

2.主键优化

·数据组织方式:

在innoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(简称IOT)

回顾之前的逻辑存储结构:

表空间(里面存储一个个段)-->段(里面存储一个个区)-->区(大小固定为1M,里面存储一个个页)-->页(大小固定为16K,里面存储一个个行)-->行(当中存放的就是具体的字段值)

页是innoDB磁盘管理的最小单元,一个页大小默认为16K,也就意味着一个区当中可以包含64个页。接下来我们看一下当我们往数据库表结构中插入数据的时候它的流程是什么样的。

主要理解好页分裂和页合并的原理是什么

·页分裂

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

可知如果主键乱序插入即可能会导致页分裂现象

·页合并

当删除一行记录时,实际上记录并没有被物理删除,只是记录被标记为删除并且它的空间变得允许被其它记录声明使用。当页中删除的记录达到 MERGE_THRESHOLD(默认为页的50%),innoDB会开始寻找最靠近的页(前或后)看看是否可以将两个页合并以优化空间使用。

·主键设计原则:

>满足业务需求的情况下,尽量降低主键的长度。

我们知道二级索引是可以有很多个嘛,而二级索引叶子节点存储的就是主键,如果你主键长度太长,那么就会占用大量的磁盘空间,而且在搜索的时候会耗费大量的磁盘io

>插入数据时,尽量选择顺序插入,选择使用AUTO_INCREMENT自增主键。

>尽量不要使用UUID做主键或者是其它自然主键,如身份证号。

>业务操作时,避免对主键的修改。

3.order by优化

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

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

所以尽量优化为using index。

为什么会出现using filesort呢?因为没有用到索引,通过创建索引再执行就可以优化为using index,出现using index就说明我们的排序效率比较高,因为它直接通过索引给我们返回了有序数据。

例:

总结:

>根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则

>尽量使用覆盖索引

>多字段排序,一个升序一个降序,此时要注意联合索引在创建时的规矩(ASC/DESC)

>如果不可避免的出现filesort,大数据量排序时,可以适当增大排序缓冲区大小sort_buffer_size(默认256K)

4. group by 优化

分组操作的时候,我们主要研究的就是索引对分组操作的影响。

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

>分组操作时,索引的使用也需要满足最左前缀法则的

5.limit优化

对于limit来说,对于大数据量的情况下你进行分页查询,越往后它的效率越低耗时越长。所以在大数据量的情况下我们就需要对limit分页操作进行优化。

一个常见又非常头疼的问题是limit2000000,10,此时需要MySQL排序前2000010记录,仅仅返回2000000-2000010的记录,其它记录丢弃,查询排序的代价非常大。

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

6.count优化

>MyISAM引擎把一个表的总行数存在了磁盘上,因此执行count(*)的时候会直接返回这个数,效率很高,不过前提是查询时后面没有where条件哈;

>InnoDB引擎就麻烦了,它执行count(*)的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数,所以这个就比较耗时了。

优化思路:自己计数

·count的几种用法:

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

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

接下来就学习这几种用法以及它的性能

>count(主键)

InnoDB引擎会遍历整张表,把每一行的主键id值都取出来,返回给服务层。服务层拿到主键后,直接按行进行累加(不用判断是不是null,因为主键不可能为null)

>count(字段)

没有 not null 约束:InnoDB会遍历整张表把每一行的字段值都取出来,返回给服务层,服务层判断是否为null,不为null,计数累加。

有not null约束:InnoDB引擎会遍历整张表,把每一行的主键id值都取出来,返回给服务层。服务层拿到主键后,直接按行进行累加。

>count(1)

InnoDB引擎遍历整张表,但是不取值。服务器对于返回的每一行,放一个数字"1"进去,直接按行进行累加。

>count(*)

InnoDB引擎并不会把全部字段取出来,因为数据库专门做了优化,不取值,服务层直接按行进行累加

哪哪个效率高呢?

就看它取不取值,你看count(*)count(1)都不取值,count(主键)取主键值,count(字段)看情况。

所以按照效率排序的话,count(字段)<count(主键id)<count(1)=count(*),所以用count求总数时尽量使用count(*)

7.update优化(避免行锁升级为表锁)

之前我们学InnoDB的时候提到了它的三大特性:事务,外键,行级锁。也就是说在InnoDB引擎中我们当前默认的事务隔离级别是行锁。

进行update语句的时候,如果后面条件没有索引,那么行锁就会升级为表锁。

如比如某表id有索引,name没有建立索引

然后你还update student set no=‘200103080020’ where name='陈小画';就会引起行锁升级为表锁

所以进行update语句的时候,我们一定要根据索引字段进行更新,否则就会造成行锁升级为表锁,就会锁住整张表,那一旦锁表了,我们的并发性能就会降低。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

排好队,一个一个来:宫本武藏教你学队列(附各种队列源码)

文章目录前言&#xff1a;理解“队列”的正确姿势一个关于队列的小思考——请求处理队列的两大“护法”————顺序队列和链式队列数组实现的队列链表实现的队列循环队列关于开篇&#xff0c;你明白了吗&#xff1f;最后说一句前言&#xff1a; 哈喽&#xff01;欢迎来到黑洞晓…

货物摆放 (蓝桥杯) JAVA

题目描述 小蓝有一个超大的仓库&#xff0c;可以摆放很多货物。 现在&#xff0c;小蓝有n 箱货物要摆放在仓库&#xff0c;每箱货物都是规则的正方体。 小蓝规定了长、宽、高三个互相垂直的方向&#xff0c;每箱货物的边都必须严格平行于长、宽、高。 小蓝希望所有的货物最终摆…

可换皮肤的Qt登录界面

⭐️我叫忆_恒心,一名喜欢书写博客的在读研究生👨‍🎓。 如果觉得本文能帮到您,麻烦点个赞👍呗! 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三连支持一下呗。👍⭐️❤️ 可换皮肤的Qt登录界面 QSS的学习笔记 快…

真是一篇神奇的文章 动图DIY - 动图剪辑 - 录屏 - 画画动图 (无需VIP的软件推荐)

很多人想自己去搞一些 动图 &#xff0c;去了好多网址或者app&#xff0c;不是收费 &#x1f4b4; 就是 VIP &#x1f511; &#xff0c;博主也苦恼了好久&#xff0c;今天遇到一款超级、无敌、好用的软件 ScreeTogif &#xff0c;下载连接 &#x1f617;&#x1f619;&#x1…

高通开发系列 - Sensors Bring Up

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 返回高通开发系列 - 总目录 目录 问题背景高通android sensor信息Sensors Execution Environment (SEE)qxdm抓sensor log的方法android 调试…

Hadoop之Mapreduce序列化

目录 什么是序列化&#xff1a; 什么是反序列化&#xff1a; 为什么要序列化&#xff1a; Java的序列化&#xff1a; Hadoop序列化: 自定义序列化接口&#xff1a; 实现序列化的步骤&#xff1a; 先看源码进行简单分析&#xff1a; 序列化案例实操&#xff1a; 案例需…

蓝桥杯真题——自动售水机

2012年第四届全国电子专业人才设计与技能大赛“自动售水机”设计任务书1. 系统框图接下来我们将任务分块&#xff1a; 1. 按键控制单元 设定按键 S7 为出水控制按键&#xff0c;当 S7 按下后&#xff0c;售水机持续出水&#xff08;继电器接通&#xff0c;指示 灯 L10 点亮&…

Java中的JSON序列化和反序列化

文章目录Java 和 JSON 序列化JSON 简介JSON 是什么JSON 标准JSON 优缺点JSON 工具Java JSON 库JSON 编码指南Fastjson 应用添加 maven 依赖Fastjson API定义 Bean序列化反序列化Fastjson 注解JSONFieldJSONTypeJackson 应用添加 maven 依赖Jackson API序列化反序列化容器的序列…

开箱即用的密码框组件

写了一个小玩具&#xff0c;分享一下 - 组件功能&#xff1a; 初次进入页面时&#xff0c;密码隐藏显示&#xff0c;且无法查看真实密码 当修改密码时&#xff0c;触发键盘&#xff0c;输入框则会直接清空 此时输入密码&#xff0c;可以设置密码的隐藏或显示&#xff1a; …

Spark了解

目录 1 概述 2 发展 3 Spark和Hadoop 4 Spark核心模块 1 概述 Apache Spark是一个快速、通用、可扩展的分布式计算系统&#xff0c;最初由加州大学伯克利分校的AMPLab开发。 Spark可以处理大规模数据处理任务&#xff0c;包括批处理、迭代式算法、交互式查询和流处理等。Spa…

算法强化每日一题--组队竞赛

大家好 先看看题目 链接&#xff1a;组队竞赛__牛客网 [编程题]组队竞赛 牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值a_i.现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人.牛牛发现队伍的水平值等于该队伍队员中第二高水平值。 例如: 一个队…

pytest学习和使用21-测试报告插件allure-pytest如何使用?

21-测试报告插件allure-pytest如何使用&#xff1f;1 Allure简介2 环境配置2.1 allure-pytest插件安装2.2 pytest安装2.3 allure文件下载2.4 allure环境变量配置2.5 配置java环境3 查看allure版本4 运行allure4.1 测试用例4.1 执行方法4.3 报告查看方法4.4 指定报告生成的端口4…

使用TensorFlow Serving进行模型的部署和客户端推理

目的&#xff1a;在一个server端使用TensorFlow框架对模型进行训练和保存模型文件后用TensorFlow Serving进行部署&#xff0c;使得能在客户端上传输入数据后得到server端返回的结果&#xff0c;实现远程调用的效果。环境&#xff1a;操作系统&#xff1a; ubuntu 20.04.1当然可…

函数(上)——“Python”

各位CSDN的uu们你们好呀&#xff0c;今天小雅兰的内容是Python的函数呀&#xff0c;下面&#xff0c;就让我们进入函数的世界吧 首先可以选择性地看一下小雅兰很久之前写的C语言函数章节的知识&#xff1a; 函数——“C”_认真学习的小雅兰.的博客-CSDN博客 函数递归&#xf…

【进阶数据结构】二叉搜索树经典习题讲解

&#x1f308;感谢阅读East-sunrise学习分享——[进阶数据结构]二叉搜索树 博主水平有限&#xff0c;如有差错&#xff0c;欢迎斧正&#x1f64f;感谢有你 码字不易&#xff0c;若有收获&#xff0c;期待你的点赞关注&#x1f499;我们一起进步 &#x1f308;我们在之前已经学习…

鸟哥的Linux私房菜 Shell脚本

第十二章、学习 Shell Scripts https://linux.vbird.org/linux_basic/centos7/0340bashshell-scripts.php 12.2 简单的 shell script 练习 #!/bin/bash# Program: # User inputs his first name and last name. Program shows his full name.read -p "Please in…

【SpringMVC】SpringMVC方式,向作用域对象共享数据(ModelAndView、Model、map、ModelMap)

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ 向域对象共享数据一、使用 原生ServletAPI二、…

渲染机制(四):硬件加速

文章目录一、概述二、硬件绘制与软件绘制模型三、软件绘制刷新的逻辑四、总结五、参考一、概述 从 Android 3.0&#xff08;API 级别 11&#xff09;开始&#xff0c;Android 2D 渲染管道支持硬件加速&#xff0c;也就是说&#xff0c;在 View 的画布上执行的所有绘制操作都会使…

【C++】C++11新特性——可变参数模板|function|bind

文章目录一、可变参数模板1.1 可变参数的函数模板1.2 递归函数方式展开参数包1.3 逗号表达式展开参数包1.4 empalce相关接口函数二、包装器function2.1 function用法2.2 例题&#xff1a;逆波兰表达式求值2.3 验证三、绑定函数bind3.1 调整参数顺序3.2 固定绑定参数一、可变参数…

Docker入门到放弃笔记之容器

1、启动容器1.1容器hello world1.2 容器bash终端1.3 后台运行容器是 Docker 三大核心概念之一&#xff0c;其余两个是镜像与仓库。本文主讲容器。简单的说&#xff0c;容器是独立运行的一个或一组应用&#xff0c;以及它们的运行态环境。对应的&#xff0c;虚拟机可以理解为模拟…