08 SQL优化

news2024/12/27 13:33:28

上一篇文章记录了索引的创建、使用、设计,除了索引方面还需要注意平日对于SQL的使用,对SQL进行优化;SQL的优化是建立在索引使用的基础上

这篇笔记将从以下7个方面对SQL进行优化。

1. 插入数据

  1. 使用批量插入,避免循环单条插入

    注意批量插入不要超过1000条;若超出则可以将记录进行拆分后分批插入

  2. 手动进行事务的提交

    开启和提交事务比较耗时,可以执行完多个命令后,手动提交事务

  3. 主键顺序插入

    插入的时候按照主键从小到大的顺序进行插入,降低维护索引耗费的时长

  4. 大批量插入数据时使用load指令

    如果有大批量数据需要导入,我们可以使用load指令将表的磁盘文件导入到数据库中

load指令

# 在客户端连接服务端的时候,加上参数--local-infile
mysql --local-file -u root -p;
# 查看参数local_infile,默认值为0
select @@local_infile;
# 设置全局允许加载MySQL数据文件
set global local_infile = 1;
# 加载数据, load data local infile为固定格式
load date local infile '/root/sql1.log' into table 'table_name' fields terminated by ',' lines terminated '\n';

2. 主键优化

在Innodb引擎中,表数据是根据索引组织存放的,这种存储方式称为索引组织表

主键优化方式:

  1. 降低主键长度

    节省空间,使页中存放更多数据,减少树的层数

  2. 尽量顺序插入,降低页分裂

    降低页分裂

  3. 不要使用uuid,最好要有顺序例如自增

    降低页分裂

  4. 业务操作不要修改主键

    降低页分裂和页合并

页分裂

Innodb中数据存储的最小单元为页,在主键顺序插入时,会按顺序填充页,一个页满了之后继续填充下一个页形成双向链表

但是当主键乱序插入的时候,假设有A、B两个页,两个页都是满的,由于乱序插入需要在A、B两个页中间插入一条记录,这时需要A分裂出一半数据放入新页C中同时把该记录放入C中;由于页的分裂比较浪费性能,因此插入的时候最好按照主键从小到大的顺序插入

插入和更新操作都可以触发页分裂

参考:https://blog.csdn.net/weixin_44228698/article/details/119057511

页合并(拓展):

innodb中删除一条记录时并不是立即删除,而是在页中标记为已删除,使得其占用空间可以被其他记录引用,在页合并的时候彻底删除掉

当一个页中被删除的数据达到MERGE_THRESHOLD(默认为页体积的50%)时,Innodb开始寻找该页前或后的页判断能否合并这两个页,当另一个页正好使用的空间不足50%,就可以合并这两个页为一个,空白的那个页可以继续记录数据

删除和更新可以触发页合并

页分裂图解

在这里插入图片描述

页合并图解

在这里插入图片描述

3. order by优化

使用explain查看order by语句执行计划,在extra中有两种:Using indexUsing filesort两种

  1. Using index:通过索引可以直接完成排序,效率很高
  2. Using filesort:通过索引或者全表扫描找到数据后;需要将数据加载到sort buffer排序缓冲区中进行排序;所有不是通过索引直接返回数据的都是File sort排序;效率较低

因此我们如果优化order by语句也是通过索引来进行入手

  1. order by也需要遵守最左前缀法则,如果order by字段没有最左侧的索引,那么索引将失效
  2. 尽量使用覆盖索引
  3. 多字段排序,一个升序一个降序,此时需要注意联合索引在创建时的规则(ASC、DESC)
  4. 如果不可避免要使用filesort,在大数据量的时候可以增加sort_buffer_size设置排序缓冲区的大小(默认256k)

4. group by优化

与order by优化类似,使用explain查看group by执行计划,发现extra中也有两种:Using temporalUsing index两种

  1. Using temporal:使用临时表,效率较低
  2. Using index:直接通过索引返回记录

因此我们如果优化group by语句也是通过索引来进行入手

  1. 遵守最左前缀法则,避免索引失效

5. limit优化

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

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

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

6. count优化

通常我们使用count的时候有四种方式:count(*),count(主键), count(1), count(某一列);对于Myisam引擎,磁盘直接将一个表的总行数记录在了引擎上,使用count(*)的时候直接返回了这个总行数,而Innodb引擎需要遍历每一行将数据从引擎中读出来再累计计数

四种方式的区别:

  1. count(*):遍历每一行,但是不取数据,服务层直接进行累加
  2. count(1):遍历每一行,但是不取数据,服务层在每一行中加入一个1,直接按行进行累加
  3. count(主键):遍历每一行,取出每一行中的主键,服务层拿到主键后按行进行累加
  4. count(某一列):遍历每一行,取出每一行中的该列,服务层判断该列是否为null,不为null的话进行累加

因此执行效率从快到慢为:count(*) ≈ count(1) > count(主键) > count(某一列)

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

我们都知道Myisam引擎为表级锁,Innodb为行级锁,那么我们在update的时候需要避免行锁升级为表锁

在A事务中执行下面sql(name上没有索引),则会导致行锁升级为表级锁,使另一个事务阻塞

update student set sex = '男' where name = '赵四';

因为Innodb的行级锁针对索引加的锁而不是针对记录的,如果没有使用到索引或者索引失效,就会升级为成表级锁

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

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

相关文章

贤鱼的刷题日常(数据结构栈学习)--P1175 表达式的转换--题目详解

🏆今日学习目标: 🍀例题讲解P1175 表达式的转换 ✅创作者:贤鱼 ⏰预计时间:25分钟 🎉个人主页:贤鱼的个人主页 🔥专栏系列:c 🍁贤鱼的个人社区,欢…

ServletConfig 和 ServletContext

1 ServletConfig 1.1 ServletConfig 介绍 ServletConfig 是 Servlet 的配置参数对象,在 Servlet 的规范中,允许为每一个 Servlet 都提供一些初始化的配置。所以,每个 Servlet 都有一个自己的 ServletConfig。作用:在 Servlet 的…

静息态fMRI中的非线性功能网络连接

在这项工作中,我们关注功能网络中的显式非线性关系。我们介绍了一种使用归一化互信息(NMI)计算不同大脑区域之间非线性关系的技术。我们使用模拟数据演示了我们提出的方法,然后将其应用到Damaraju等人先前研究过的数据集。静息状态fMRI数据包括151名精神…

玩转高并发,17年开发经验架构师,历时三年编写Java高并发三部曲

前言 5G,IO,多屏合一,方物互联时代来了!太分n式、高并发、微服务架构己经成为Java后端应用的主流架构。但是对Java高并发,springcloudRPC底层原理、Nginx底层原理等核心知识,广大的Java开发同学们相对欠缺…

【踩坑汇总】CLion开启QT编程

一下全部内容全都是大佬lht的经验,我只是记录一下给大家。 问题:Qt5Config.cmake找不到 解决办法: set(CMAKE_PREFIX_PATH "E:/Qt/Qt5.12.11/5.12.11/mingw73_64/lib/cmake/Qt5") 找到Qt5Config.cmake路径,添加上面这…

东南亚LazadaShopee文具类目好做吗?一文带你了解各国热销及需求品类

在东南亚,消费者刚刚经历完双11独有的“速度与激情”——11月11日00:11,开售11分钟,Lazada平台的销售额相比日销暴涨124倍;早上8:17,第一单跨越重洋的中国跨境商品就已成功送达签收。 东南亚&a…

Listen,Attend,and Spell(LAS)——李宏毅人类语言处理学习笔记3

Listen Encoder目标: 去掉noises,提取出相关信息 encoder有很多做法: CNN见文章:CNN-卷积神经网络 self-attention见文章self-attention Pyramid RNN将两个结合,然后送到下一层。Pooling over time则是两个中取一…

代谢组学文献分享:地中海饮食、血浆代谢组和心血管疾病风险

​全球三分之一的死亡由心血管疾病造成,2015-2020年美国膳食指南建议,地中海饮食是预防心血管疾病的一项重要且具有成本效益的战略措施。代谢组学文献分享,发表在期刊European Heart Journ-al(IF 22.637)上题目为“Th…

网络协议

网络通信协议:计算机网络中实现通信必须有一些约定,即通信协议,对速率、传输代码、代 码结构、传输控制步骤、出错控制等制定标准。 问题:网络协议太复杂:计算机网络通信涉及内容很多,比如指定源地址和目标…

【多标签, 极限的多标签算法】评价指标梳理

具体研究多标签和极限多标签 (XML) 的时候, 合理使用评价指标是关键. 最近在研究极限多标签算法的时候发现了它和传统多标签算法的评价指标是有异的, 而且我曾经积累的传统多标签评价指标也没有一个系统的体系 (很混乱). 于是写下本文用于自我总结. 查询目录<想看什么直接通…

语音识别翻译怎么做?这些方法值得收藏

随着网络的不断发展&#xff0c;我们可以通过网络与世界各地的网友进行聊天。小伙伴们平时会和外国人交流吗&#xff1f;如果是文字聊天&#xff0c;我们看不懂的时候&#xff0c;还可以直接复制文字进行翻译。那如果外国网友发了段语音&#xff0c;结果我们大部分内容听不懂的…

电力行业人员定位管理解决方案之智能巡检

智能巡检引入大数据分析理念&#xff0c;通过数字化技术实现对生产现场各关键要素的全面感知和实时互联&#xff0c;形成项目现场“数据一个库、监管一张网、管理一条线“。 在信息技术高速发展的今天&#xff0c;传统人工巡视、手工纸介质记录的工作方式已经无法满足电力设备巡…

第7章 博客文章的前端渲染显示

说实话本人通过Vue页面实现前端对后端数据的渲染显示也是初学咋练&#xff0c;但后端实现本人却是老鸟&#xff0c;对于后端开发者来说如果&#xff0c;渲染显示的软件是浏览器&#xff0c;除非团队中有Vue方面的大拿&#xff0c;不管是PC浏览器还是移动PC浏览器&#xff0c;Ra…

元宇宙初体验

14天学习训练营导师课程&#xff1a; 张子良《 元宇宙体系结构、关键技术和实践探索》 前言 最近这段时间加入勤学会的学习中&#xff0c;我加入的是元宇宙相关的学习组&#xff0c;为什么我选择元宇宙&#xff0c;不仅因为元宇宙是应用场景和生活方式的未来&#xff0c;而且元…

启动 idea 弹出“Failed to load JVM DLL\bin\server\jvm.dll”错误的解决方法

打开idea报failed to load JVM DLL 原因1&#xff1a; 查看是否缺少Microsoft Visual C 2010 Redistributable Package x64&#xff0c;没有则安装。 地址&#xff1a; 32 bit: http://www.microsoft.com/download/en/details.aspx?id5555 64 bit: http://www.microsoft.com…

面试必问 创建10个a点击弹出下标

<script> // for (let i 1; i <11; i) { // var adocument.createElement("a"); // a.href"#"; // a.innerHTML"<br />a标签"i // document.body…

JDBC获取数据库连接

Driver接口实现类 Driver接口介绍 java.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的&#xff0c;不同数据库厂商提供不同的实现。 在程序中不需要直接去访问实现了 Driver 接口的类&#xff0c;而是由驱动程序管理器类(java.sql.…

Android学习---zygote(上)

Zygote意思是受精卵&#xff0c;它在Java世界中起到了很重要的作用&#xff0c;Android是基于Linux内核的&#xff0c;SDK是基于Java世界的&#xff0c;native语言是基于C和C&#xff0c;起初一定是先存在native世界&#xff0c;那么Java世界是如何创建的&#xff1f;这就与zyg…

『LeetCode|每日一题』---->打家劫舍||

目录 1.每日一句 2.作者简介 『LeetCode|每日一题』打家劫舍|| 1.每日一题 2.解题思路 2.1 思路分析 2.2 核心代码 2.3 完整代码 2.4 运行结果 1.每日一句 任何事情把期待值降到最低&#xff0c;所有遇见的都是礼物 2.作者简介 &#x1f3e1;个人主页&#xff1a;XiaoXia…

github数据怎么Python爬取

爬虫流程 在上周写完用scrapy爬去知乎用户信息的爬虫之后&#xff0c;github上star个数一下就在公司小组内部排的上名次了&#xff0c;我还信誓旦旦的跟上级吹牛皮说如果再写一个&#xff0c;都不好意思和你再提star了&#xff0c;怕你们伤心。上级不屑的说&#xff0c;那就写…