MySQL进阶——SQL优化

news2024/11/25 10:36:32

目录

1插入数据

1.1 insert

1.2大批量插入数据

2主键优化

3 order by 优化

4 group by 优化

5 limit 优化

6 count 优化

6.1概述

6.2 count用法

7 update优化

1插入数据

1.1 insert

优化方案主要有3种

批量插入数据

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

手动控制事务

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

1.2大批量插入数据

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

(1)客户端连接服务端时,加上参数 --local-infile

mysql --local-infile -u root -p

(2)设置全局参数local_infile为1或on,开启从本地加载文件导入数据的开关

 set global local_infile = 1;

(3)在finalshell底栏上传数据到sql文件夹,然后可以进行查看

wc -l tb_sku1.sql;  #看看数据有多少行,-L是不定

head tb_sku1.sql;  #看看数据的前10行

(4)执行load指令将准备好的数据,加载到表结构中:

load data local infile '/root/sql/tb_sku1.sql' into table `tb_sku` fields terminated by ',' lines terminated by '\n';

每个字段逗号,分隔,每行数据\n分隔。

2主键优化

(1)数据组织方式

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

(2)主键乱序插入时,会出现页分裂的现象,比较耗性能

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

(4)主键索引的设计原则

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

太长会占用磁盘空间,在搜索查询时会占用磁盘IO,

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

乱序插入可能会出现页分裂现象,耗费性能。

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

UUID是无序的,且很长

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

3 order by 优化

MySQL的排序,有两种方式:

(1)Using filesort : 通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sort buffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫 FileSort 排序。 (2)Using index : 通过有序索引顺序扫描直接返回有序数据,这种情况即为 using index,不需要 额外排序,操作效率高。

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

案例:

(1)将tb_user2这个表的索引删减到这些。

(2)现在按照age和phone排序,都是使用Using filesort进行排序的,因为这两个字段都没有索引。

(3)创建联合索引(age,phone)

create index idx_user_age_phone on tb_user2(age,phone);

升序联合索引结构图示:

(4)现在再来排序查询

联合索引是age为第一个字段,上面两个先按照age排序,都是按照Using index的方式,但是下面两个出现了Using filesort,是因为违背了最左前缀法则。

(5)反向扫描

在B-Tree中的叶子节点,按照age升序,如果age相同,再按照phone升序(创建索引不指定时默认升序)。这里都要倒序,就需要反向扫描。

(6)一升一降

因为创建索引没有指定排序,就默认是升序,这里phone要降序,就需要额外的排序。

(7)创建索引指定排序方向(优化!!!)

create index idx_user_age_phone_ad on tb_user2(age asc,phone desc);

(8)这时候再一升一降就是按照索引了,没有额外的了

order by优化原则:

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

B. 尽量使用覆盖索引(不要使用select *,尽量不要造成回表查询)。

C. 多字段排序, 一个升序一个降序,此时需要注意联合索引在创建时的规则ASC/DESC

D. 如果不可避免的出现filesort,大数据量排序时,可以适当增大排序缓冲区大小

sort_buffer_size(默认256k)。

修改缓冲区大小的代码:

show variables like 'sort_buffer_size';

set sort_buffer_size=262145;

4 group by 优化

(1)删掉除开主键以外的索引

drop index idx_user_email_5 on tb_user2;

(2)没有索引时,执行分组操作

分组就不要select*,没有任何意义,查询sql执行发现用到了临时表Using temporary 。

(3)创建索引再查询——尽量创建联合索引(profession,age,status)

create index idx_user_pro_age_sta on tb_user2(profession,age,status);

发现查询profession,age都是利用的索引

(4)遵守最左前缀法则

当跳过第一个字段profession,直接用age

explain select age,count(*) from tb_user2 group by age;

但是profession不一定要在group by后面,只要出现了就行。

5 limit 优化

在数据量比较大时,如果进行limit分页查询,在查询时,越往后,分页查询效率越低。

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

SQL代码:select * from tb_sku limit 1000000,10;

优化方法:覆盖索引+子查询

In后面不能用到limit这样的关键字,不支持这种语法。

错误SQL:select * from tb_sku where id in(select * from tb_sku limit 1000000,10);

正确SQL代码:

select s.* from tb_sku s,(select * from tb_sku limit 1000000,10) a where s.id=a.id;

6 count 优化

6.1概述

如果数据量很大,在执行count操作时,是非常耗时的(默认是InnoDB 引擎)。

(1)MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) 的时候会直接返回这个 数,效率很高; 但是如果是带条件的count,MyISAM也慢。

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

6.2 count用法

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

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

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

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

(3)count(数字) InnoDB 引擎遍历整张表,但不取值。服务层对于返回的每一行,放一个数字“1” 进去,直接按行进行累加。

(4)count(*) InnoDB引擎并不会把全部字段取出来,而是专门做了优化,不取值,服务层直接 按行进行累加。

按照效率排序的话,count(字段) < count(主键 id) < count(1) ≈ count(*),

所以尽量使用 count(*)

7 update优化

优化:更新字段时最好根据索引字段更新(InnoDB 引擎默认是行锁。)

如果更新索引字段,则事务执行时只会锁住这一行,如事务1锁住id=4的行,不会影响id=1的行操作。update course set name = 'C++' where id = 1;

如果不是用索引字段,则会将整个表锁住。

如下事务1用的非索引字段name,在未提交前将整个表都锁住了,事务2就只能等待。

事务2在事务1提交完之后才能执行。

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

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

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

相关文章

详解 ClickHouse 的副本机制

一、简介 副本功能只支持 MergeTree Family 的表引擎&#xff0c;参考文档&#xff1a;https://clickhouse.tech/docs/en/engines/table-engines/mergetree-family/replication/ ClickHouse 副本的目的主要是保障数据的高可用性&#xff0c;即使一台 ClickHouse 节点宕机&#…

Web渗透-CSRF跨站请求伪造

跨站请求伪造&#xff08;Cross-Site Request Forgery&#xff0c;CSRF&#xff09;是一种网络攻击&#xff0c;通过利用受害者的身份认证状态在不知情的情况下执行恶意操作。通常&#xff0c;这种攻击会诱使用户点击恶意链接或访问一个特制的网站&#xff0c;从而触发不被用户…

python库BeeWare,一个如雷贯耳的可以创建原生应用程序的库

目录 BeeWare 包括以下主要组件和工具&#xff1a; 创建BeeWare虚拟环境 配置BeeWare 创建一个新的BeeWare项目&#xff08; Hello World! &#xff09; 尝试 Hello World 样例 BeeWare 是一个开源项目&#xff0c;旨在帮助开发者使用 Python 创建原生应用程序&#xff0c;…

后端路线指导(4):后端春招秋招经验分享

后端春招&秋招经验分享 春招(暑期实习) /秋招是应届生非常重要的应聘时间,每一个想就业的同学一定要有所了解! 本篇内容&#xff0c;老白将与大家分享暑期实习和秋招如何应对招聘的个人经验&#xff0c;希望每个同学看完都能有所收获! 首先说明一下老白对于面试核心竞争力的…

Android图片圆角转换 RoundedImageView开源项目 小记

属性的意义: makeramen:border_width“2dip” 表示图片的边框宽度为2个dp makeramen: corner_radius表示为 图片转圆角的弧度 修改 makeramen:corner_radius“100dip” 当 corner_radius 设置为100dp 的时候 会呈现为圆形 . ( 注: com.makeramen.rounded.Ro…

MySQL表的增删改查初阶(下篇)

本篇会加入个人的所谓鱼式疯言 ❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言 而是理解过并总结出来通俗易懂的大白话, 小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的. &#x1f92d;&#x1f92d;&#x1f92d;可能说的不是那么严谨.但小编初心是能让更多人…

多重排序【今日题记】

多重排序 多重排序题目分析思路代码代码结构体知识多重排序 需要对多个条件进行排序,因此可以称之为多重排序。 题目 某生物实验室记录了n种(n<=1000)病毒信息,每种病毒都有编号、传染性和致病性三个基本信息,编号是1000-9999的人工编号,其中的传染性和致病性是用0-10…

SVN学习(002 svn冲突解决)

尚硅谷SVN高级教程(svn操作详解) 总时长 4:53:00 共72P 此文章包含第20p-第p29的内容 冲突 产生冲突的操作 &#xff08;第一种 相互不影响的操作&#xff09; 用户1修改第二行 用户2修改第四行 用户1提交 用户2提交&#xff0c;提交的时候会提示版本已过时 这时将用…

力扣SQL 即时食物配送 II min函数 嵌套查询

Problem: 1174. 即时食物配送 II &#x1f468;‍&#x1f3eb; 参考题解 Code -- 计算立即配送的订单百分比 select round (-- 计算订单日期与客户偏好配送日期相同的订单数量sum(case when order_date customer_pref_delivery_date then 1 else 0 end) * 100 /-- 计算总订…

掌握Three.js:学习路线,成为3D可视化开发的高手!

学习Three.js可以按照以下路线进行&#xff1a; 基础知识&#xff1a; 首先要了解基本的Web开发知识&#xff0c;包括HTML、CSS和JavaScript。如果对这些知识已经比较熟悉&#xff0c;可以直接进入下一步。 Three.js文档&#xff1a; 阅读Three.js官方文档是学习的第一步。官…

如何下载和安装SQLynx数据库管理工具? (MySQL作为测试数据库)

目录 1. 官网下载 2. 安装软件 3. 启动SQLynx软件 4. 开始使用 5. 执行第一条SQL语句 6. 总结 SQLynx是一款先进的Web SQL集成开发环境&#xff08;IDE&#xff09;&#xff0c;专为数据库管理、查询和数据分析设计。作为一个基于浏览器的工具&#xff08;同时也支持桌面…

掌握 NumPy:高效数组处理综合指南(第 1/2 部分)

掌握 NumPy&#xff1a;高效数组处理综合指南&#xff08;第 1/2 部分&#xff09; 文章目录 一、介绍二、什么是Numpy&#xff0c;我们为什么要使用它&#xff1f;三. 数组初始化四. 计算速度和内存使用量五、内存使用情况六、数据类型七、索引和切片 一、介绍 你们以前听说过…

连接和断开信号演示之二

代码; #include <gtk-2.0/gtk/gtk.h> #include <gtk-2.0/gdk/gdkkeysyms.h> #include <glib-2.0/glib.h> #include <stdio.h>void button_press(GtkEventBox *ebox,GdkEventButton *event,GtkLabel *label) {const char *citem;switch(event->type…

[图解]建模相关的基础知识-15

1 00:00:01,030 --> 00:00:05,820 接下来&#xff0c;我们就开始讲解的知识点 2 00:00:05,830 --> 00:00:11,810 就是范式知识点 3 00:00:12,130 --> 00:00:17,490 关系这个理论里面&#xff0c;随着历史的发展 4 00:00:17,700 --> 00:00:21,280 它发展出很多的…

力扣随机一题 模拟+字符串

博客主页&#xff1a;誓则盟约系列专栏&#xff1a;IT竞赛 专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 1910.删除一个字符串中所有出现的给定子字符串【中等】 题目&#xff1a; …

基于STM32的智能工厂环境监测系统

目录 引言环境准备智能工厂环境监测系统基础代码实现&#xff1a;实现智能工厂环境监测系统 4.1 数据采集模块4.2 数据处理4.3 控制系统实现4.4 用户界面与数据可视化应用场景&#xff1a;智能工厂管理与优化问题解决方案与优化收尾与总结 1. 引言 智能工厂环境监测系统通过…

【转】FreeRTOS通用移植,以keil和IAR工程 M7核为例

目录 keil: IAR keil: 原文在https://bbs.eeworld.com.cn/thread-1281875-1-1.html 本篇讲述移植FreeRTOS,并创建运行一个任务&#xff0c;对象芯片为M7系列的兆易创新GD32H7xx系列。 一.准备工作 1.下载FreeRTOS源码官网 http://www.freertos.org/ 或者托管网站FreeRTOS…

Vue71-嵌套(多级)路由

一、需求 二、开发步骤 2-1、编写路由组件 2-2、编写路由规则 2-3、编写路由标签<router-link>、<router-view> 三、小结

(vue3)基于vite+vue3+element-plus项目创建

(vue3)基于vitevue3element-plus项目创建 vue.js官方中文文档&#xff1a;https://cn.vuejs.org/guide/quick-start.html vite官方中文文档&#xff1a;https://cn.vitejs.dev/guide/ element-plus官网&#xff1a;https://element-plus.org/zh-CN/guide/installation.html 第…

Github 2024-06-19 C开源项目日报 Top9

根据Github Trendings的统计,今日(2024-06-19统计)共有9个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量C项目9C++项目1Netdata: 开源实时监控平台 创建周期:4020 天开发语言:C协议类型:GNU General Public License v3.0Star数量:68982 个Fork数量…