SQL优化

-插入数据

批量插入:(一次尽量不超过1000条)

Insert into tb test values(1,'Tom'),(2,'cat'),(3, Jerny');

手动事务提交:

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;

主键顺序插入:

取决于mysql数据组织结构(后面会将主键优化),将插入主键按从小到大进行排列。

大批量数据插入:

如果一次性需要插入大批量数据,使用insert语句插入性能较低,此时可以使用MYSQL数据库提供的load指令进行插入。操作如下。

#客户端连接服务端时,加上参数--local-infile
mysql --local-infile -u root -p
#设置全局参数local infile为1,开启从本地加载文件导入数据的开关
select @@local infile;//查看是否开启0否1是
set global local infile =1;
#执行load指令将准备好的数据,加载到表结构中以","隔开字段。每一行通过"\n"分割
load data local infile '/root/sql1.log' into table `tb_user` fields terminated by ',' lines terminated by '\n';

注意:

load插入时最好也按照主键顺序插入,顺序插入性能会高于乱序插入。(为什么请看主键优化)

  • 主键优化

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

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

主键顺序插入示意图:

页分裂:

若主键乱序插入因xxxx可能会造成页分裂

页合并:

当删除一行记录时,实际上记录并没有被物理删除,只是记录被标记(flaged)为删除并且它的空间变得允许被其他记录声明使用。

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

知识小贴士:

MERGE_THRESHOLD:合并页的阈值,可以自己设置,在创建表或者创建索引时指定。

主键的设计原则:

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

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

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

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

order by优化:

1、Using filesor:通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sortbufer中完成排序操作,所有不是通过索引直

接返回排序结果的排序都叫 FileSort 排序。

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

#没有创建索引时,根据age,phone进行排序
explain select id,age,phone from tb_user order by age , phone,
#创建索引
create index idx_user_age_phone_aa on tb_user(age,phone),
#创建索引后,根据age,phone进行升序排序
explain select id,age,phone from tb_user order by age , phone,
#创建索引后,根据age,phone进行降序排序
explain select id,age,phone from tb_user order by age desc , phone desc ;

补充:

在创建索引时默认是升序的(从小到大)

但是也可以在创建是改变排序顺序:

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

该方法创建的索引先通过年龄升序排序然后相同年龄的按手机号倒序排序。

总结:

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

尽量使用覆盖索引。

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

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

如果超过排队缓冲区将会占用磁盘空间,会影响性能。

增加排队缓冲区
show variables like 'sort_buffer_size';//查看排队缓冲区大小
SET sort_buffer_size='2M';//设置排队缓冲区的大小为2M

group by优化:

#删除掉目前的联合索引
drop index idx_user pro_age_sta on tb_user;
#执行分组操作,根据profession字段分组
explain select profession , count(*) from tb_user group by profession;
#创建索引
create index idx_user_pro_age_sta on tb_user(profession,age,status);
#执行分组操作,根据profession字段分组
explain select profession, count(*) from tb_user group by profession ;
#执行分组操作,根据profession字段分组
explain select profession,count(*) from tb_user group by profession, age,

使用总结:

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

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

limit分页 优化

一个常见又非常头疼的问题就是 limit 2000000,10,此时需要MYSQL排序前20000,10 记录,仅仅返回2000000-2000010

的记录,其他记录丢弃,查询排序的代价非常大。

优化方式:通过覆盖索引加子查询的方式

原SQL语句:缺点性能低  只需要查询10条数据其他数据进行丢弃,严重占用服务器的缓存、速度慢
select * from tb_sku limit 9000000,10; 优化后:
第一步:
select id from tb_sku order by id limit 9000000,10;//先查询需要的id, 并对其排序 最终sql
错误写法:原因-mysql不支持在in里面写limit
select * from tb_sku where id in (select id from th sku order by id limit 9000000,10);
正确写法:
select s.* from tb_sku s,(select id from tb sku order by id limit 9000000,10) a where s.id = a.id;

总结:

尽量避免使用大的偏移量,如limit 10000,10,因为这会导致MySQL扫描大量无用的行。

尽量结合where子句来过滤不需要的数据,以减少扫描的行数。

尽量使用有序的索引来避免文件排序,以提高查询效率。

count优化

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

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

count的工作原理:

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

count的用法以及优化思路:

count(主键):

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

count(字段):

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

有not nul 约束:InnoD8 引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,直接按行进行累加。

count(1):

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

count(*):

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

效率排序:

count(字段)<count(主键 id)<count(1)~ count(),所以尽量使用 count()。

update优化

mysql进阶-SQL优化篇的更多相关文章

  1. mysql的sql优化案例

    前言 mysql的sql优化器比较弱,选择执行计划貌似很随机. 案例 一.表结构说明mysql> show create table table_order\G***************** ...

  2. 我的mysql数据库sql优化原则

    原文 我的mysql数据库sql优化原则 一.前提 这里的原则 只是针对mysql数据库,其他的数据库 某些是殊途同归,某些还是存在差异.我总结的也是mysql普遍的规则,对于某些特殊情况得特殊对待. ...

  3. MySQL之SQL优化详解(二)

    目录 MySQL之SQL优化详解(二) 1. SQL的执行顺序 1.1 手写顺序 1.2 机读顺序 2. 七种join 3. 索引 3.1 索引初探 3.2 索引分类 3.3 建与不建 4. 性能分析 ...

  4. 基于MySQL 的 SQL 优化总结

    文章首发于我的个人博客,欢迎访问.https://blog.itzhouq.cn/mysql1 基于MySQL 的 SQL 优化总结 在数据库运维过程中,优化 SQL 是 DBA 团队的日常任务.例行 ...

  5. 【MySQL】SQL优化系列之 in与range 查询

    首先我们来说下in()这种方式的查询 在<高性能MySQL>里面提及用in这种方式可以有效的替代一定的range查询,提升查询效率,因为在一条索引里面,range字段后面的部分是不生效的. ...

  6. mysql索引sql优化方法、步骤和经验

    MySQL索引原理及慢查询优化 http://blog.jobbole.com/86594/ 细说mysql索引 https://www.cnblogs.com/chenshishuo/p/50300 ...

  7. (1.10)SQL优化——mysql 常见SQL优化

    (1.10)常用SQL优化 insert优化.order by 优化 1.insert 优化 2.order by 优化 [2.1]mysql排序方式: (1)索引扫描排序:通过有序索引扫描直接返回有 ...

  8. MySQL之SQL优化详解(一)

    目录 慢查询日志 1. 慢查询日志开启 2. 慢查询日志设置与查看 3.日志分析工具mysqldumpslow   序言: 在我面试很多人的过程中,很多人谈到SQL优化都头头是道,建索引,explai ...

  9. Mysql的SQL优化指北

    概述 在一次和技术大佬的聊天中被问到,平时我是怎么做Mysql的优化的?在这个问题上我只回答出了几点,感觉回答的不够完美,所以我打算整理一次SQL的优化问题. 要知道怎么优化首先要知道一条SQL是怎么 ...

  10. BATJ解决千万级别数据之MySQL 的 SQL 优化大总结

    引用 在数据库运维过程中,优化 SQL 是 DBA 团队的日常任务.例行 SQL 优化,不仅可以提高程序性能,还能减低线上故障的概率. 目前常用的 SQL 优化方式包括但不限于:业务层优化.SQL 逻 ...

随机推荐

  1. 《Python数据可视化之matplotlib实践》 源码 第四篇 扩展 第十二章

    图  12.1 import matplotlib.pyplot as plt import numpy as np barSlices=12 theta=np.linspace(0.0, 2*np. ...

  2. nvidia显卡服务器,负载严重,温度爆表,如何解决 —— 降低功率、降频

    设置功率为180W: sudo nvidia-smi -pl 180 为指定显卡设置功率: (-i 后接显卡号) sudo nvidia-smi -pl 180 -i 0,1,2,3

  3. idea中多线程debug实现方案

    1.背景 2.步骤 步骤一: 步骤二: 步骤三: 启动测试,查看个线程状态 完美

  4. 再探GraphRAG:如何提升LLM总结能力?

    作者:王振亚 编者语: 自微软发布GraphRAG之后,相关解读文层出不穷,其中不乏优秀的内容.比如前段时间转载薛明同学的<微软GraphRAG框架源码解读>让大家快速对GraphRAG的 ...

  5. Keil uVision5软件破解方法

    1.正常下载软件 2.右键"管理员方式运行"软件 3.如下图"File"->"License..." 4.复制CID,管理员方式打开破 ...

  6. 是技术牛人,如何拿到国内IT巨头的Offer

    不久前,byvoid面阿里星计划的面试结果截图泄漏,引起无数IT屌丝的羡慕敬仰.看看这些牛人,NOI金牌,开源社区名人,三年级开始写Basic...在跪拜之余我们不禁要想,和这些牛人比,作为绝大部分技 ...

  7. WinForm 使用委托动态更新数据

    使用委托动态更新数据 详细代码 // 声明一个委托,用于更新消息的文本提示 private delegate void UpdateMsgTextDelegate(string text); // 定 ...

  8. zblog免费插件分享前端代码支持一键复制

    zblog默认的代码文件在网页前端是不支持一键复制的,这会让访客复制长代码的时候不太方便,甚至有可能会出错,影响体验,下面分享一个非常简单的免费插件,安装之后,前端代码就能一键复制了. 插件使用方法: ...

  9. 5个必知的高级SQL函数

    5个必知的高级SQL函数 SQL是关系数据库管理的标准语言,用于与数据库通信.它广泛用于存储.检索和操作数据库中存储的数据.SQL不区分大小写.用户可以访问存储在关系数据库管理系统中的数据.SQL允许 ...

  10. 使用 nuxi generate 进行预渲染和部署

    title: 使用 nuxi generate 进行预渲染和部署 date: 2024/9/4 updated: 2024/9/4 author: cmdragon excerpt: 通过 nuxi ...