• 1
  • 0
分享

1、MySQL基础

1.1 MySQL的基本知识

按照惯例,先介绍一下 MySQL基本知识:

MySQL 是一种关联数据库管理系统,关联数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。

MySQL 的 SQL “结构化查询语言”,是用于访问数据库的最常用标准化语言。

MySQL 软件采用了 GPL(GNU 通用公共许可证),由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本,而选择 MySQL 作为其网站数据库。

1.2 MySQL的优势

MySQL的优势有哪些,我们来瞧瞧。

・MySQL开源的,无需支付额外费用的;

・MySQL使用标准的SQL数据语言形式;

・MySQL可以运行多个系统上,并支持多个语言(如:C、C++、Python、Java、Perl、PHP、Eiffel、Ruby 等);

・MySQL可以定制,采用 GPL 协议,可修改源码来开发自己的 MySQL 系统。 

所以,我们要搞好MySQL数据库,是不是非常有必要。

今天,

我们就先从 order by和group by来说起。

2、order by 原理

2.1 创建表

为了更好,更容易理解相关知识点,咱先举个例子。

也是小鱼的一贯作风, 举例说话 !

先创建一张测试表,

/* auth:carl_奕然  */
 /* 使用ClassDJ这个database */
 use ClassDJ;  
 /* 如果表t1存在则删除表t1 */
 drop table if exists t1;  
 /* 创建表t1 */
 CREATE TABLE 't1'(      
 'id' int(11) NOT NULL AUTO_INCREMENT,
 'a' int(20) DEFAULT NULL ,
 'b' int(20) DEFAULT NULL ,
 'c' int(20) DEFAULT NULL ,
 'd' datetime NOT NULL  DEFAULT CURRENT_TIMESTAMP ,
 PRIMARY KEY (`id`),
 KEY `idx_a_b` (`a`,`b`),
 KEY `idx_c` (`c`)
 )ENGINE=InnoDB CHARSET=utf8mb4 ;
 /* 如果存在存储过程insert_t1,则删除 */
 drop procedure if exists insert_t1;
 delimiter ;;
 /* 创建存储过程insert_t1 */
 create procedure insert_t1()
 begin 
   /* 声明变量i */
   declare i int;  
   /* 设置i的初始值为1 */
   set i=1; 
   /* 对满足i<=10000的值进行while循环 */
   while(i<=10000)do
   /* 写入表d1中a、b两个字段,值都为i当前的值 */
     insert into t1(a,b,c) values(i,i,i); 
     /* 将i加1 */
     set i=i+1;    
   end while;
 end ;;
 delimiter ;
  /* 运行存储过程insert_t1 */
 call insert_t1();       
 /* 将id大于9000的行的a字段更新为1000 */
 update t1 set a=1000 where id >9000;

创建完表,我们就来研究一下MySQL的排序原理 

2.2 MySQL的排序方式

按照排序原理分,MySQL 排序方式分两种:

    ①通过有序索引直接返回有序数据

    ②通过Filesort进行的排序 

那么,问题来了,

如何确定某条排序的SQL所使用的排序方式?

答:使用explain来查看该排序SQL的执行计划,重点关注****字段。

★如果Extra字段里显示是 Using index,则表示是通过有序索引直接返回有序数据 

例如;

explain select id,c from t1 order by c;

20201102171156796.png

★如果Extra字段里显示是 Using filesort,则表示该 SQL 是通过 Filesort 进行的排序 

例如:

explain select id,d from t1 order by d;

2020110217122756.png

是不是,这就一目了然 了。

Nice

2.3 Filesort 在哪里完成排序

MySQL 中的 Filesort 并不一定是在磁盘文件中进行排序的,也有可能在内存中排序,

内存排序还是磁盘排序取决于排序的数据大小和 sort_buffer_size 配置的大小。

・如果 “排序的数据大小” < sort_buffer_size: 内存排序

・如果 “排序的数据大小” > sort_buffer_size: 磁盘排序

同样,问了又来了, 

如何确定使用 Filesort 排序的 SQL 是在内存还是在磁盘中进行的排序操作? 

答:使用 trace 进行分析重点关注 number_of_tmp_files,

★如果等于 0,则表示排序过程没使用临时文件,在内存中就能完成排序;

★如果大于0,则表示排序过程中使用了临时文件。

举例

一、未使用临时文件排序

20201102171959866.png

上图中,因为 number_of_tmp_files 等于 0,表示未使用临时文件进行排序,所以是内存排序。

参数解析:

・rows:预计扫描的行数

・examined_rows:参与排序的行

・number_of_tmp_files:使用临时文件的个数

・sort_buffer_size:sort_buffer 的大小

・sort_mode:排序模式

二、使用临时文件排序

20201102172253996.png

上图中,因为 number_of_tmp_files 等于 7,所以表示使用的是磁盘排序。

 number_of_tmp_files 等于 7表示:

该SQL 将需要排序的数据分为 7 份,然后每份单独排序,再存放在 7 个临时文件中,最后把 7 个临时文件合并成一个大的有序文件。

2.4 Filesort 下的排序模式

一、排序模式

Filesort 下的排序模式有三种: 

    ・< sort_key, rowid >双路排序(又叫回表排序模式):是首先根据相应的条件取出相应的排序字段和可以直接定位行数据的行 ID,然后在 sort buffer 中进行排序,排序完后需要再次取回其它需要的字段;

    ・< sort_key, additional_fields >单路排序:是一次性取出满足条件行的所有字段,然后在sort buffer中进行排序;

    ・< sort_key, packed_additional_fields >打包数据排序模式:与单路排序相似,区别是将 char 和 varchar 字段存到 sort buffer 中时,更加紧缩。

MySQL 通过比较系统变量 max_length_for_sort_data 的大小和需要查询的字段总大小来判断使用哪种排序模式 

二、判断排序模式

通过 max_length_for_sort_data 的大小和需要查询的字段总大小来判断使用哪种排序模式。

・如果 max_length_for_sort_data 比查询字段的总长度大,那么使用 < **sort_key, additional_fields >**排序模式;

・如果 max_length_for_sort_data 比查询字段的总长度小,那么使用 <sort_key, rowid> 排序模式。

三、实例举例

① 

set session optimizer_trace="enabled=on",end_markers_in_json=on;
 SET max_length_for_sort_data = 20;
 /* 查询表d1的id、a、d三个字段的值,按照字段d进行排序  */
 select a,d from t1 order by d; 
 SELECT * FROM information_schema.OPTIMIZER_TRACE\G

 OPTIMIZER_TRACE 结果中排序信息,如下图:

202011021733387.png

可以看到,使用的是**<sort_key,additional_fields>**排序模式。

我们要是变成 <sort_key, rowid>,怎么整呢?

思路:因为 a、d 两个字段的总长度为 12,可以尝试把 max_length_for_sort_data 改为小于 12 的值,看排序模式是否有改变。

操作:

set session optimizer_trace="enabled=on",end_markers_in_json=on;
SET max_length_for_sort_data = 4;
/* 查询表d1的id、a、d三个字段的值,按照字段d进行排序  */
select a,d from t1 order by d; 
SELECT * FROM information_schema.OPTIMIZER_TRACE\G

OPTIMIZER_TRACE 结果中排序信息,如下图:

20201102173732939.png

看看,是不是变成 <sort_key ,rowid>排序模式了。

非常Nice。

嗯,今天的就到这里,

关于如何优化orderby 及groupby ,我会在下一篇中着重介绍:

深聊MySQL之:让orderby、groupby查询速度飞起来(下)


  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          •   日前,沃尔沃首款纯电MPV车型沃尔沃EM90的谍照在网上曝光。据悉,这款特供车将采用和极氪009相同的SEA浩瀚架构,车身长度可能超过5.2米。计划于今年第三季度亮相并投产上市,成为沃尔沃90车系的第四款车型。  根据谍照可以看出,新车外观与极氪009有诸多相似之处,如雷神之锤轮廓的LED大灯组和镀铬饰条点缀的封闭式进气格栅。车身侧面包括悬浮式车顶造型、双层镂空的A柱和C柱的转折点造型以及充电口位置等细节与极氪009几乎一致。然而,由于伪装措施严实,尾部设计等细节尚不清晰可见。  动力方面,沃尔沃EM90将采用纯电驱动系统,可能与EX90采用相同的动力配置:低功率版电机最大功率407马力,...
            0 0 446
            分享
          • 摘要本文是基于高德地图开放者平台,利用python语言调用第三方库requests、Pandas、BeautifulSoup,爬取高德实时交通监控平台发布的重庆市城市道路实时路况数据(2020年5月30日早上7:30、中午12:00、下午17:30三个时段)。通过ArcGIS10.4软件,将实时路况信息进行符号化处理。关键词高德地图;python;实时路况;ArcGIS引言实时路况是针对城市交通道路畅通和拥堵情况所提出的一个概念,它能有效反映区域内实时交通情况,为行驶车辆能够进行最佳行驶路线提供参考,提高道路的交通效率和缓解交通拥堵。具体的实时路况信息是通过对道路路况信息的匹配,使用绿色、黄色...
            13 13 1502
            分享
          •   美国商务部长吉娜-雷蒙多(Gina Raimondo)周二表示,没有证据表明中国制造商华为可以大批量生产采用先进芯片的智能手机。  华为最近开始销售一款名为Mate 60 Pro的手机,分析师认为这款手机的芯片是由中芯国际(0981.HK)利用突破性技术制造的。  雷蒙多在美国众议院听证会上提到一种先进芯片时说:"我们没有任何证据表明他们可以大规模生产7纳米(芯片)。"  美国商务部本月早些时候表示,它正在努力获取更多信息,以"了解"可能违反贸易限制的芯片的"特性和成分"。雷蒙多在众议院科学委员会听证会上表示,她对华为智能手机的先...
            0 0 498
            分享
          •   1、前言  大家好!我是Meng  前段时间,很荣幸被一合作伙伴邀请发表一篇文章,主题为"这些年,我所从事软件测试的一些感悟",正好趁着这个机会,我也好好总结一下。  2、测试培训  对于软件测试,在培训之前也不知道是干什么的,只知道有软件开发,之后才知道有软件测试这个行业。  刚开始也是在徘徊是做开发还是做测试,经过多次被测试机构的招生老师洗脑后,开始进行了软件测试培训之旅。那时候测试培训机构就那么几家,基本都是机构,个人的很少,培训机构是线下的,线上的也很少。培训价格方面也是过万了,跟现在的培训机构差不多,也就便宜了几千而已。  回头一想想,那时候教的内容,真的很少...
            0 0 787
            分享
      • 51testing软件测试圈微信