黑马程序员--mysql高级 --sql优化相关笔记

2022/1/9 2:04:00

本文主要是介绍黑马程序员--mysql高级 --sql优化相关笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1.5.sql的优化

QQ截图20220105164024

1.5.1.查看sql的执行频率

MySQL 客户端连接成功后,通过 show [session|global] status 命令可以查看服务器状态信息。通过查看状态信息可以查看对当前数据库的主要操作类型。

--下面的命令显示了当前 session 中所有统计参数的值
show session status like 'Com_______';  -- 查看当前会话统计结果
show global  status  like 'Com_______';  -- 查看自数据库上次启动至今统计结果
 
show status like 'Innodb_rows_%’;       -- 查看针对Innodb引擎的统计结果

QQ截图20220105164159

1.5.2.执行效率比较低的sql的定位

可以通过以下两种方式:

  • 慢查询日志 : 通过慢查询日志定位那些执行效率较低的 SQL 语句。

  • show processlist:该命令查看当前MySQL在进行的线程,包括线程的状态、是否锁表等,可以实时地查看 SQL 的执行情况,同时对一些锁表操作进行优化。

慢查询日志

-- 查看慢日志配置信息 
show variables like '%slow_query_log%’; 

-- 开启慢日志查询 
set global slow_query_log=1; 

-- 查看慢日志记录SQL的最低阈值时间 
show variables like 'long_query_time%’; 

-- 修改慢日志记录SQL的最低阈值时间 
set global long_query_time=4;

show processlist

show processlist;

各个参数的意义:

QQ截图20220105164437

1.5.3.explain分析执行计划

通过以上步骤查询到效率低的 SQL 语句后,可以通过 EXPLAIN命令获取 MySQL如何执行 SELECT 语句的信息,包括在 SELECT 语句执行过程中表如何连接和连接的顺序。

QQ截图20220105164545

其中各个 参数的含义为:
QQ截图20220105164603

对id的解释

QQ截图20220105164700

QQ截图20220105164738

QQ截图20220105164754

对select_type的解释

QQ截图20220105164900

对type的解释

QQ截图20220105164942

各个type的展示

  • NULL

QQ截图20220108092344

  • system

QQ截图20220108092907

  • const(查询唯一索引时)
    在这里插入图片描述

  • eq_ref(左表有主键索引 且左表每一行和右表刚好匹配)

    举个例子:我们创建两个表 user2 和 user2_ex

4

5

结果所示:当user2 和 user_ex的行恰好一一对应的时候查找模式为all(因为有 * )和eq_ref

而添加一个重复元素后,就不能使用eq_ref了,效率降低。

  • ref (左表为普通索引时)

7

ref允许左表匹配右表多行。

  • range(范围查询)

8

  • index (打印索引列)

9

  • all (普通的全表查询)

重点是这个比较的大于顺序,一定要记牢,优化时候尽量把它维持在index等级之上。

其他指标(key 等)

QQ截图20220108205029
11]

QQ截图20220108205230

12

1.5.4.使用show profile分析sql

QQ截图20220108205640

15

查找步骤 : 使用查找语句> show profiles展示>找到你要分析语句的序号> show profile for 你要找的语句

可以如上图最后一条 查找语句的cpu占用。

QQ截图20220108210055

1.5.5.mysql的具体优化策略

1.依靠索引优化

创建组合索引,提高查找速度。要时刻遵循最左匹配法则,不能跳过。 要注意,实际查询值越高,就使用了越多的索引,速度越高。

16

17

  • 如果跳过一个索引,违反最左原则,将会失效

18

  • 范围查询,运算操作和单引号失去会使索引失去效果

19

  • 避免使用* 因为查询除索引以外的数据需要从磁盘读取,效率较低

20

对比

同样的道理password没加索引,效率下降。

22

extra各个指数的指代意义

23

  • or会引起索引失效

24

25

  • 模糊索引

26

  • 即使有索引,不用索引的情况

当我们一个列重复的数据较多时,我们查找重复的数据时,比如在下图找地址在北京的数据。数据库会自动为我们全表查询,此时全表查询效率较高。

而查找西安市的时候,会使用索引查询。

27

28

29

30

not in和in跟上面 道理一样 多就不用索引。

31

  • 尽量使用复合索引
    在这里插入图片描述

  • 当一个查询条件包括三个单列索引时,取最优的生效

34

  • 查询时,联表查询优于嵌套子查询

在这里插入图片描述

2.优化order by

下面的显示来自extra

在这里插入图片描述

QQ截图20220108212908

尽量顺序一致,排序方式相同

36

3.优化Filesort

当我们迫不得已使用Filesort 时

通过创建合适的索引,能够减少 Filesort 的出现,但是在某些情况下,条件限制不能让Filesort消失,那就需要加快 Filesort的排序操作。对于Filesort , MySQL 有两种排序算法:

1) 两次扫描算法 :MySQL4.1 之前,使用该方式排序。首先根据条件取出排序字段和行指针信息,然后在排序区 sort buffer 中排序,如果sort buffer不够,则在临时表 temporary table 中存储排序结果。完成排序之后,再根据行指针回表读取记录,该操作可能会导致大量随机I/O操作。

2)一次扫描算法:一次性取出满足条件的所有字段,然后在排序区 sort buffer 中排序后直接输出结果集。排序时内存开销较大,但是排序效率比两次扫描算法要高。

MySQL 通过比较系统变量 max_length_for_sort_data 的大小和Query语句取出的字段总大小, 来判定是否那种排序算法,如果max_length_for_sort_data 更大,那么使用第二种优化之后的算法;否则使用第一种。

可以适当提高 sort_buffer_size 和 max_length_for_sort_data 系统变量,来增大排序区的大小,提高排序的效率。

在这里插入图片描述

4.优化limit

这么写
在这里插入图片描述

或者

41

5.大批插入数据的优化

当我们要用.log文件导入大量数据,怎么做才更有效率呢?

插入方法

-- 1、首先,检查一个全局系统变量 'local_infile' 的状态, 如果得到如下显示 Value=OFF,则说明这是不可用的
show global variables like 'local_infile';
 
-- 2、修改local_infile值为on,开启local_infile
set global local_infile=1;
 
-- 3、加载数据 

load data local infile 'D:\\sql_data\\sql1.log' into table tb_user fields terminated by ',' lines terminated by '\n';

  • 按照主键列排好顺序

QQ截图20220108213436

  • ​ 关闭唯一检索

    mysql在添加数据时会检测唯一索引的数据是否重复。如果我们事先已经检查好,就可以关闭唯一检索,提高效率。

    -- 关闭唯一性校验
    SET UNIQUE_CHECKS=0;
     
    truncate table tb_user;
    load data local infile 'D:\\sql_data\\sql1.log' into table tb_user fields terminated by ',' lines terminated by '\n';
     
    SET UNIQUE_CHECKS=1;
    
    

6.优化insert

三个方向

  1. 有序插入

    -- 数据有序插入
    insert into tb_test values(4,'Tim');
    insert into tb_test values(1,'Tom');
    insert into tb_test values(3,'Jerry');
    insert into tb_test values(5,'Rose');
    insert into tb_test values(2,'Cat');
     
     
    -- 优化后
    insert into tb_test values(1,'Tom');
    insert into tb_test values(2,'Cat');
    insert into tb_test values(3,'Jerry');
    insert into tb_test values(4,'Tim');
    insert into tb_test values(5,'Rose');
    
  2. 尽量集中插入

    -- 如果需要同时对一张表插入很多行数据时,应该尽量使用多个值表的insert语句,这种方式将大大的缩减客户端与数据库之间的连接、关闭等消耗。使得效率比分开执行的单个insert语句快。
    
    -- 原始方式为:
    insert into tb_test values(1,'Tom');
    insert into tb_test values(2,'Cat');
    insert into tb_test values(3,'Jerry');
     
     
    -- 优化后的方案为 : 
     
    insert into tb_test values(1,'Tom'),(2,'Cat'),(3,'Jerry');
    	
    
  3. 用一个事务插入(记得提前关了自动提交)

-- 在事务中进行数据插入。
begin;
insert into tb_test values(1,'Tom');
insert into tb_test values(2,'Cat');
insert into tb_test values(3,'Jerry');
commit;



这篇关于黑马程序员--mysql高级 --sql优化相关笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程