SQL语句的优化

插入数据

大量插入数据load,使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令进行插入。

复制代码
mysql--local-infile -u root -p;     客户端连接服务端加上参数--local-infile
set global local_infile = 1;        设置全局参数local—file为1,开启从本地加载文件导入数据的开关
执行load指令将准备好的数据,加载到表结构当中
load data local infile '/root/sql1.log' into table 'tb_user' fields terminated by ','lines terminated by '/n'

主键顺序插入要高于乱序插入

主键优化

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

主键顺序插入的时候b+树的根叶子结点会维护一个双向的链表,使主键顺序的插入。

页分裂

因为页可以为空或者也可以插不满,所以每个页包含了2-n行数据(如果一行数据多大,会行溢出)。当主键乱序插入的时候就有可能会出现页分裂的现象

页合并

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

当页中的记录达到MERGE-THRESHOLD(默认为页的50%),InnoDB会开始寻找最靠近的页,看看是否可以将两个页进行合并。

主键的设计原则:

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

  2. 插入数据时,尽量顺序插入。

  3. 尽量不要使用uuid做主见,或者其他自然主键。

  4. 尽量避免对主键的修改。

order by优化:

  1. Using filesort:通过表的索引或全表扫描,读取吗,满足条件的数据行,让后在排序缓冲区sort buffer 中完成排序操作,所有不是通过索引直接返回结果的排序都叫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 ;

注意:order by进行优化的时候尽量用using index,默认创建的索引都是升序,当我们查询的时候如果不全是升序,那么还是会出现using filesort 所以我们可以穿件倒序的索引

复制代码
#根据age,phone进行降序一个升序,一个降序
explain select id,age,phone from tb user order by age asc , phone desc;
#创建索引
create index idx user age phone ad on tb user(age asc ,phone desc),
#根据age,phone进行降序一个升序,一个降序
explain select id,age,phone from tb user order by age asc , phone desc,

如图为创建索引的时候出现索引结构的情况。

注意:

  1. 我们需要多字段建立合适索引,多字段排序时也会遵循最左前缀法则(有优先级)。

  2. 尽量使用覆盖索引。

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

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

group by优化:

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

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

limit优化:

  • limit深度查询是一个较为头疼的问题,当查询的深度较深时,查询的代价会非常的大。

  • 优化思路:

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

    复制代码
    explain select * from tb sku t , (select id from tb sku order by id limit 2000000,10) a wheret.id = a.id,

count优化:

count没有比较好的优化:在myASIM的存储引擎当中,会将其存在内存当中,没有查询条件的count(*)语句。

count的几种用法:

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

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

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

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

Update优化:

  1. 在InnODB里面,行锁是针对索引加的锁,并不是针对记录加的锁,所以在使用Update语句的时候,要避免出现表锁的情况,同样的索引不能够失效,否则也会从行锁升级为表锁。

总结:

复制代码
1. 插入数据   
     1. insert:批量插入,手动控制事务,主键顺序插入。  
     2. 大批量插入:load data local infile
2. 主键优化:   
     - 主键长度尽量的短,并且主键要按照顺序插入,同时选择主键的时候要选择自增且有序的,uuid不可取,因为过长且无序,容易造成页分裂。
3. order by优化:    
    1. using index:直接通过索引返回数据。    
    2. using filesort:需要将返回结果放在排序缓冲区排序。    
    - 在实际应用中优化尽量使其using index。
4. group by优化:    
    1. 索引和多字段满足最左前缀法则。
5. limit优化:    
    1. 覆盖索引+子查询
6. count优化:    
    1. count(字段)<count(主键)<count(1)~count(*)
7. update优化:    
    1. 尽量根据主键,索引字段进行更新。
相关推荐
FixPng1 分钟前
【数据库】《DBA实战手记》- 读书笔记
数据库·dba
小李今天工地加班22 分钟前
Windows安装PostgreSQL(16.9)
数据库·postgresql
码农开荒路43 分钟前
Redis线程模型
数据库·redis·缓存
快乐非自愿1 小时前
接口重试的7种常用方案!
服务器·数据库·php
supermapsupport1 小时前
SuperMap GIS基础产品FAQ集锦(20250603)
服务器·数据库·webgl·supermap·idesktop
文牧之1 小时前
PostgreSQL的扩展 passwordcheck
运维·数据库·postgresql
bing_1581 小时前
如何合理设计缓存 Key的命名规范,以避免在共享 Redis 或跨服务场景下的冲突?
数据库·redis·缓存
健康平安的活着1 小时前
mysql数据库实现分库分表,读写分离中间件sharding-sphere
数据库·mysql·中间件
黑客笔记2 小时前
安全大模型的思考
数据库·安全·web安全
穗余2 小时前
NodeJS全栈开发面试题讲解——P3数据库(MySQL / MongoDB / Redis)
数据库·mysql·node.js