mysql 查询优化

Mysql优化之高级

一、exists和in - - - 小表驱动大表

前言: 50010000和10000500,在数学角度来说是没什么区别的,从java角度来说是这样的:

for(int i=0;i<500;i++){
    for(int j;j<10000;j++){
    }
}

for(int i=0;i<10000;i++){
    for(int j;j<500;j++){
    }
}

但是对于mysql来说是有区别的。这关系到连接和释放的次数。

简介: exists和in到底谁性能好是没有绝对一说的,这需要看表数据的大小。

in: SELECT * FROM dept where deptno in (SELECT deptno FROM emp )这句sql,在mysql翻译之后是这样的:

for(SELECT deptno FROM emp) {
    for(SELECT * FROM dept where emp.deptno =dept.deptno){

    }
}

exists: SELECT * FROM dept where EXISTS (SELECT 1 FROM emp where emp.deptno =dept.deptno)这句sql,在mysql翻译之后是这样的(这里的1可以换成任意常量,比如A、a之类的):

for(SELECT deptno FROM dept ) {
    for(SELECT * FROM dept where emp.deptno =dept.deptno){

    }
}

分析: 如果使用in,则需要连接emp的条数次;如果使用exists,则需要连接dept 的条数次。

案例:向emp中插入100万条记录,向dept表中插入5万条记录。

这里写图片描述

这里写图片描述

结论: emp表比dept表小的时候使用in,emp表比dept表大的时候使用exists。即:内小in,外小exists。

二、order by 之 filesort

简介: order by的排序总共有两种,一种是使用索引(index)进行排序,还有一种是没法使用索引进行排序的,称为filesort排序(文件排序)。using index效率比using filesort高。

准备工作:

CREATE TABLE test01 (
c1  varchar(3)  ,
c2  varchar(3),
c3  varchar(3),
c4 varchar(3)
);
create index  c1c2c3 on test01(c1,c2,c3);
insert into test01 values('a1','a2','a3','a4');
insert into test01 values('b1','b2','b3','b4');

几种常见的场景:

1、只有order by 没有where条件:这个可能其他版本的mysql是不会产生filesort的(因为我看到网上说这种情况是不会产生的),我也没试过,但是mariadb的10.0.17版本是会产生的

这里写图片描述

这里写图片描述

2、where条件中有c1,但是order by中没有c1,只有c2和c3

这里写图片描述

3、where 条件中有c1 ,但是order by中只有c3: 这个就属于中间兄弟丢了

这里写图片描述

4、where条件中有c1,但是order by中没有c1,只有c2和c3,而且c2正序,c3倒序:必须同正同逆

这里写图片描述

5、where条件中有c1,order by中有c1、c2和c3,但是order by c1 ,c3,c2:必须要和复合索引字段顺序一致

这里写图片描述

6、where 条件中有c1 ,但是c1的条件是个范围,order by中只有c2和c3: 范围之后全失效

这里写图片描述

7、where 条件中有c1 ,但是c1的条件是个范围,order by中有c1、c2和c3:

这里写图片描述

8、where条件中没有c1,有c2,但是order by中有c1:这个可能不同版本之间也有不同的答案

这里写图片描述

9、where条件中没有c1,但是order by中也没有c1,只有c2和c3: 这个就属于带头大哥死了

这里写图片描述

总结: 产生filesort的原因主要有:

1、带头大哥或者中间兄弟丢了。

2、order by之后的字段顺序和复合索引中的字段顺序不一致。

3、没有where条件(不同版本的mysql可能不一样)

4、尚硅谷总结图:


这里写图片描述

filesort的两种算法:双路排序和单路排序

双路排序: mysql在4.1之前使用的都是双路排序,字面的意思就是两次扫描磁盘,最终得到数据。即:读取行指针和order by 列,对他们进行排序,然后扫面已经排序好的列表,按照列表中的值重新从列表中读取对应的数据输出。简单来说就是:从磁盘中读取需要排序的字段,在buffer中进行排序,然后再从磁盘中读取其他字段。

单路排序: 双路排序需要读取两次磁盘,但是i/o是非常消耗内存和时间的,所以,能不能将读取磁盘的时间减少为1次呢?于是就有了单路排序:从磁盘中读取查询需要的所有列,按照order by列在buffer中对他们进行排序,然后扫描排序之后的列表进行输出,他的效率要比双路快,因为他将每一行的所有字段都保存在了内存中。

单路排序的缺点: 因为单路是将所有的字段都放在了内存中,假如,这张表是在太大,大的超过了sort_buffer这个值了,那么每次都只能取sort_buffer的数据,来进行排序(会创建临时tmp文件,然后多路合并),相当于多路了,这样一来效率比双路还要差。

优化单路:

1、尽量少用select *,想要那个字段就查那个。

2、在配置文件中增大sort_buffer_size 参数的值。

3、适当调大max_length_for_sort_data,这个值将会决定filesort使用哪种算法,如果查询的字段大小综合小于这个值,那么将会使用单路算法,否则使用双路算法。但是如果设置的太高,因为单路算法是查询所有字段,这样就会导致单路超过sort_buffer_size的可能性增大,从而产生单路的缺点。

三、group by 之 temporary

简介: 分组之前必排序,换句话说,有using temporary 的地方必定有using filesort。using temporary 的意思就是创建临时文件,using filesort的意思就是使用文件排序,两者都是导致你查询速度变慢的原因。

案例:

这里写图片描述

几种常见情况:

这里写图片描述

总结: 情况和order by的差不多,只是从using filesort变到了using temporary,优化方式当然是想方设法使用索引来进行排序,当然必要的时候可以修改或者重新创建一个符合需求的索引。

四、慢查询日志分析

查看是否开启: show variables like ‘%slow_query_log%’; mysql默认是关闭的,需要我们手动去打开。

这里写图片描述

开启慢查询:

1、本次有效:即重启mysql之后就会失效。set global slow_query_log=1;


这里写图片描述

注意:mysql中默认的慢查询时间为10秒,但是生产环境中怎么可能让一条sql执行10秒钟。。。


这里写图片描述

2、永久有效:即修改配置文件。这里我们配置慢查询的时间为3秒(超过三秒中的查询都会别记录到慢查询日志中)

slow_query_log=TRUE
slow_query_log_file="D:/mariaDB/mariadb-10.0.17-winx64/slow_query_log.txt"
long_query_time=3
这里写图片描述

测试: 我们可以写几句sql测试一下。

这里写图片描述

捕获慢查询: select sleep(4) 的意思就是睡眠4秒钟。我们打开慢查询日志文件(slow_query_log.txt),我们可以看到超过3秒钟的sql都被记录了下来。

这里写图片描述

</article>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,743评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,296评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,285评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,485评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,581评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,821评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,960评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,719评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,186评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,516评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,650评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,936评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,757评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,991评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,370评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,527评论 2 349

推荐阅读更多精彩内容

  • 查询sql的数学表达 1 SELECT A.,B. //投影FROM A,B ...
    Teemo_fca4阅读 4,307评论 0 0
  • Explain是我们平时使用最多的MySQL优化关键字了,了解它的使用是掌握MySQL优化的基础。当在查询语句前加...
    不知名的程序员阅读 1,347评论 0 7
  • 优化性能需要查询优化、索引优化、库表结构优化这三辆马车齐头并进。这篇文章主要围绕查询优化,要对查询进行优化首先需要...
    陈菲TW阅读 168评论 0 0
  • 一:mysql优化概述:设计角度:存储引擎的选择,字段类型选择,范式。利用mysql自身的特性:索引,查询缓存,分...
    Jason_b3e0阅读 788评论 0 2
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,513评论 16 22