MySQL调优系列——MySQL经常使用的优化技巧

SQL优化缘由:html

性能低、执行时间太长、等待时间太长、SQL语句欠佳(链接查询)、索引失效、服务器参数设置不合理(缓冲、线程数)mysql

system>const>eq_ref>ref>range>index>all   ,要对type进行优化的前提:有索引sql

其中:system,const只是理想状况;实际能达到 ref>range数据库

system(忽略): 只有一条数据的系统表 ;或 衍生表只有一条数据的主查询服务器

1.经过show status 命令了解各类sql的执行效率

2. 定位执行效率较低的SQL语句

开启慢查询记录(在相应的配置文件中添加慢查询记录sql最长时间阈值)函数

三、经过Explain分析低效率的SQL语句的执行状况

-- 实际SQL,查找用户名为Jefabc的员工
select * from emp where name = 'Jefabc';
-- 查看SQL是否使用索引,前面加上explain便可
explain select * from emp where name = 'Jefabc'

 

概要描述:性能

id:选择标识符,优先级
select_type:表示查询的类型。
table:输出结果集的表
partitions:匹配的分区
type:表示表的链接类型
possible_keys:表示查询时,可能使用的索引
key:表示实际使用的索引

key_len:索引字段的长度
ref:列与索引的比较
rows:扫描出的行数(估算的行数)
filtered:按表条件过滤的行百分比
Extra:执行状况的描述和说明 测试

下面对这些字段出现的可能进行解释:优化

1、 idspa

SELECT识别符。这是SELECT的查询序列号

个人理解是SQL执行的顺序的标识,SQL从大到小的执行

1. id相同时,执行顺序由上至下

2. 若是是子查询,id的序号会递增,id值越大优先级越高,越先被执行

3. id若是相同,能够认为是一组,从上往下顺序执行;在全部组中,id值越大,优先级越高,越先执行

-- 查看在研发部而且名字以Jef开头的员工,经典查询
explain select e.no, e.name from emp e left join dept d on e.dept_no = d.no where e.name like 'Jef%' and d.name = '研发部';

2、select_type查询中每一个select子句的类型

PRIMARY:包含子查询SQL中的 主查询 (最外层)
SUBQUERY:包含子查询SQL中的 子查询 (非最外层)
simple:简单查询(不包含子查询、union)
derived:衍生查询(使用到了临时表)

3、table

显示这一步所访问数据库中表名称(显示这一行的数据是关于哪张表的),有时不是真实的表名字,多是简称,例如上面的e,d,也多是第几步执行的结果的简称

4、type

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

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

all:查询所有表中的数据

index:查询所有索引中数据

range:检索指定范围的行 ,where后面是一个范围查询(between   ,> < >=,     特殊:in有时候会失效 ,从而转为 无索引all)

ref:非惟一性索引,对于每一个索引键的查询,返回匹配的全部行(0,多)

eq_ref:惟一性索引:对于每一个索引键的查询,返回匹配惟一行数据(有且只有1个,不能多 、不能0)

const:仅仅能查到一条数据的SQL ,用于Primary key 或unique索引  (类型 与索引类型有关)

system(忽略): 只有一条数据的系统表 ;或 衍生表只有一条数据的主查询

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

5、possible_keys

指出MySQL能使用哪一个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不必定被查询使用(该查询能够利用的索引,若是没有任何索引显示 null)

该列彻底独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。
若是该列是NULL,则没有相关的索引。在这种状况下,能够经过检查WHERE子句看是否它引用某些列或适合索引的列来提升你的查询性能。若是是这样,创造一个适当的索引而且再次用EXPLAIN检查查询

6、Key

key列显示MySQL实际决定使用的键(索引),必然包含在possible_keys中

若是没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

7、key_len

表示索引中使用的字节数,可经过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并不是实际使用长度,即key_len是根据表定义计算而得,不是经过表内检索出的)

不损失精确性的状况下,长度越短越好 

8、ref

列与索引的比较,表示上述表的链接匹配条件,即哪些列或常量被用于查找索引列上的值

9、rows

 估算出结果集行数,表示MySQL根据表统计信息及索引选用状况,估算的找到所需的记录所须要读取的行数

10、Extra

该列包含MySQL解决查询的详细信息,有如下几种状况:

Using where:不用读取表中全部信息,仅经过索引就能够获取所需数据,这发生在对表的所有的请求列都是同一个索引的部分的时候,表示mysql服务器将在存储引擎检索行后再进行过滤

Using temporary:表示MySQL须要使用临时表来存储结果集,常见于排序和分组查询,常见 group by ; order by

Using filesort:当Query中包含 order by 操做,并且没法利用索引完成的排序操做称为“文件排序”

-- 测试Extra的filesort
explain select * from emp order by name;

Using join buffer:改值强调了在获取链接条件时没有使用索引,而且须要链接缓冲区来存储中间结果。若是出现了这个值,那应该注意,根据查询的具体状况可能须要添加索引来改进能。

Impossible where:这个值强调了where语句会致使没有符合条件的行(经过收集统计信息不可能存在结果)。

Select tables optimized away:这个值意味着仅经过使用索引,优化器可能仅从聚合函数结果中返回一行

No tables used:Query语句中使用from dual 或不含任何from子句

-- explain select now() from dual;

总结:

• EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响状况
• EXPLAIN不考虑各类Cache
• EXPLAIN不能显示MySQL在执行查询时所做的优化工做
• 部分统计信息是估算的,并不是精确值
• EXPALIN只能解释SELECT操做,其余操做要重写为SELECT后查看执行计划。

注意:要尽可能避免让type的结果为all,extra的结果为:using filesort

4.适当的位置加上索引【注意如下几种状况】

  • 较频繁的做为查询条件字段应该建立索引

    select * from order_copy where id = $id

  • 惟一性太差的字段不适合单首创建索引,即便频繁做为查询条件

   select * from order_copy where sex=’女’

  • 更新很是频繁的字段不适合建立索引

    select * from order_copy where order_state=’未付款’

  • 不会出如今WHERE子句中字段不应建立索引

本文参考:

https://www.cnblogs.com/tufujie/p/9413852.html

https://www.cnblogs.com/itsharehome

相关文章
相关标签/搜索