ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

MySQL中的SQL常见调优策略测试

2020-06-16 12:05:17  阅读:289  来源: 互联网

标签:test1 explain SQL 索引 调优 MySQL c1 where select


在项目中,SQL的调优对项目的性能来讲至关重要,所有掌握常见的SQL调优方式是必不可少的,下面介绍几种常见的SQL的调优方式,供借鉴.

explain的type:

表示MySQL在表中找到所需行的方式,又称“访问类型”。

常用的类型有: ALL, index, range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)

ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行

index: Full Index Scan,index与ALL区别为index类型只遍历索引树

range:只检索给定范围的行,使用一个索引来选择行

ref: 表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值

eq_ref: 类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件

const、system: 当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,system是const类型的特例,当查询的表只有一行的情况下,使用system

NULL: MySQL在优化过程中分解语句,执行时甚至不用访问表或索引,例如从一个索引列里选取最小值可以通过单独索引查找完成。

1.避免全表扫描

对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

explain select * from test1

在这里插入图片描述

explain select * from test1 where c1 = '111'

在这里插入图片描述
我们可以看到没加where条件时,type是ALL(全表扫描),加了where的c1(索引)条件后type是ref,即哪些列或常量被用于查找索引列上的值。显然非全表扫描会快很多。

2.索引列排序

MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

explain select * from test1 where c1 = 'aaa' order by c3;

在这里插入图片描述

explain select * from test1 order by c1;

在这里插入图片描述
我们看到order by即使是用到了c1索引,type依然为ALL全表扫描。

3.like语句操作

一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引,而like “aaa%”可以使用索引。测试如下:

explain select * from test1 where c1 like '%a%';

在这里插入图片描述

explain select * from test1 where c1 like 'a%';

在这里插入图片描述

4.不要在列上进行运算或者对字段进行函数操作

例如:select * from users where YEAR(adddate)<2007,将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成:select * from users where adddate<’2007-01-01′

explain select * from test1 where id/2 = 2;

在这里插入图片描述

explain select * from test1 where id = 2*2;

在这里插入图片描述

5.MySQL只对以下操作符才使用索引:<,<=,=,>,>=,between,in,以及某些时候的like(不以通配符%或_开头的情形)。而理论上每张表里面最多可创建16个索引,不过除非是数据量真的很多,否则过多的使用索引也不是那么好玩的。

建议:一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

explain select * from test1 where c1 < 'a';

explain select * from test1 where c1 != 'aaa';

explain select * from test1 where c1 in ('aaa', 'aaa2');

explain select * from test1 where c1 not in ('aaa', 'aaa2');

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

6.避免使用or逻辑

应尽量避免在 where 子句中使用 or 来连接条件,迫不得已尽量写成IN:OR的效率是n级别,IN的效率是log(n)级别(in的个数建议控制在200以内),且用or链接条件将导致引擎放弃使用索引而进行全表扫描,如:

explain select * from test1 where c1 = 'aaa' or c2 = 'bbb';

在这里插入图片描述

explain

select * from test1 where c1 = 'aaa'

union all

select * from test1 where c2 = 'bbb';

在这里插入图片描述

7.慎用in和not in逻辑

in 和 not in 也要慎用,否则会导致全表扫描,如:

select id from t1 where num in(select id from t2 where id > 10)

此时外层查询会全表扫描,不使用索引。可以修改为:

select id from t1,(select id from t1 where id > 10)t2 where t1.id = t2.id

此时索引被使用,可以明显提升查询效率。

explain select * from test1 where c1 in (select c1 from test1);

在这里插入图片描述

explain select t1.c1,t1.c2 from test1 t1, (select c1 from test1) t where t1.c1 = t.c1;

在这里插入图片描述

8.如果列值单一,索引也可能失效

并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

9.表格字段类型选择

尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

尽可能的使用 varchar 代替 char ,因为首先可变长度字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

账号名建议用varchar,密码建议用char,varchar是可变字符的,char是固定长度的,密码通过加密后都是等长的字符。

10.查询语法中的字段

任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

标签:test1,explain,SQL,索引,调优,MySQL,c1,where,select
来源: https://blog.csdn.net/qq_46914021/article/details/106767598

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有