MySQL小结及性能优化(查看执行计划)

逻辑架构图1 

 

1.Connectors

指的是不同语言中与SQL的交互

2.Management Serveices & Utilities: 

系统管理和控制工具

3.Connection Pool: 连接池

* 管理缓冲用户连接线程处理等需要缓存的需求。

* 负责监听对 MySQL Server 的各种请求,接收连接请求,转发所有连接请求到线程管理模块。每一个连接上 MySQL Server 的客户端请求都会被分配(或创建)一个连接线程为其单独服务。

* 而连接线程的主要工作就是负责 MySQL Server 与客户端的通信,接受客户端的命令请求,传递 Server 端的结果信息等。线程管理模块则负责管理维护这些连接线程。包括线程的创建,线程的 cache 等。

4.SQL Interface: SQL接口

接受用户的SQL命令,并且返回用户需要查询的结果。比如select from就是调用SQL Interface

5.Parser: 解析器

* SQL命令传递到解析器的时候会被解析器验证和解析

主要功能:

a . 将SQL语句进行语义和语法的分析,分解成数据结构,然后按照不同的操作类型进行分类,然后做出针对性的转发到后续步骤,以后SQL语句的传递和处理就是基于这个结构的。

b.  如果在分解构成中遇到错误,那么就说明这个sql语句是不合理的

6.Optimizer: 查询优化器

* SQL语句在查询之前会使用查询优化器对查询进行优化

* 它使用的是“选取-投影-联接”策略进行查询。

     用一个例子就可以理解: select uid,name from user where gender = 1;

     * 这个select 查询先根据where 语句进行选取,而不是先将表全部查询出来以后再进行过滤

     * 这个select查询先根据uid和name进行属性投影,而不是将属性全部取出以后再进行过滤

     * 将这两个查询条件联接起来生成最终查询结果

7.Cache和Buffer: 查询缓存

他的主要功能是将客户端提交给MySQL的 select请求的返回结果集 cache 到内存中,与该 query 的一个 hash 值 做一个对应。该 Query 所取数据的基表发生任何数据的变化之后, MySQL 会自动使该 query 的Cache 失效。在读写比例非常高的应用系统中, Query Cache 对性能的提高是非常显著的。当然它对内存的消耗也是非常大的。

如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等

8.存储引擎接口

存储引擎接口模块可以说是 MySQL 数据库中最有特色的一点了。目前各种数据库产品中,基本上只有 MySQL 可以实现其底层数据存储引擎的插件式管理。这个模块实际上只是 一个抽象类,但正是因为它成功地将各种数据处理高度抽象化,才成就了今天 MySQL 可插拔存储引擎的特色。

     从图还可以看出,MySQL区别于其他数据库的最重要的特点就是其插件式的表存储引擎。MySQL插件式的存储引擎架构提供了一系列标准的管理和服务支持,这些标准与存储引擎本身无关,可能是每个数据库系统本身都必需的,如SQL分析器和优化器等,而存储引擎是底层物理结构的实现,每个存储引擎开发者都可以按照自己的意愿来进行开发。 

        注意:存储引擎是基于表的,而不是数据库

逻辑架构图2:

小tips: 

select语句中的列(非聚合函数列),必须出现在group by子句中。

group by子句中的列,不一定要出现在select语句中。

聚合函数只能出现select语句中或者having语句中,一定不能出现在where语句中。

where语句中的条件只能是数据库中已经存在的字段。

 SQL语句的执行顺序:

示例SQL:

SELECT * FROM user LEFT JOIN order ON user.id = order.uid

WHERE order.price > 5000

GROUP BY user.name

HAVING count(1) > 8

ORDER BY user.name

LIMIT 0,10

 

 执行顺序:

  1. FROM(将最近的两张表,进行笛卡尔积)---VT1(VT--->virtual table   虚表)
  2. ON(将VT1按照它的条件进行过滤)---VT2
  3. LEFT JOIN(保留左表的记录)---VT3
  4. WHERE(过滤VT3中的记录)--VT4…VTn   (根据where的条件个数来看 一个条件产生一个虚表)
  5. GROUP BY(对VT4的记录进行分组)---VT5
  6. HAVING(对VT5中的记录进行过滤)---VT6
  7. SELECT(对VT6中的记录,选取指定的列)--VT7
  8. ORDER BY(对VT7的记录进行排序)--VC8(游标)
  9. LIMIT(对排序之后的值进行分页)  从VC8的开始处选择指定数量或比例的行返回给客户端

游标:是一个对象,对表进行排序的查询可返回一个对象,该对象是包含特定的物理顺序的。

WHERE条件执行顺序(影响性能)

不同数据库where条件的执行顺序不同:

1.MySQL:从左到右的执行WHERE条件

2.Oracle:从右到左的执行 WHERE条件

3.postgreSQL:从左到右的执行WHERE条件

因此:

   写WHERE条件的时候,优先级高的部分要去编写过滤力度最大的条件语句

 

性能优化思路:

1、首先需要使用慢查询功能,去获取所有查询时间比较长的SQL语句。

2、使用explain去查看该SQl的执行计划。

3、使用show profile去查看该SQL执行时的性能问题。

 

1、MySQL的慢查询日志功能,默认是关闭的,需要手动开启

 

1.临时开启慢查询功能

在 MySQL 执行 SQL 语句设置,但是如果重启 MySQL 的话将失效

set global slow_query_log = ON;

set global long_query_time = 1;

2.永久开启慢查询功能

修改/etc/my.cnf配置文件,重启 MySQL, 这种永久生效.

[mysqld]

slow_query_log = ON

slow_query_log_file = /var/log/mysql/slow.log    MySQL数据库慢查询日志存储路径

long_query_time = 1

 

2、查看执行计划explain

 

参数说明

expain出来的信息有10列,分别是idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra,下面对这些字段进行解释:

  1. id: SELECT 查询的标识符. 每个 SELECT 都会自动分配一个唯一的标识符.
  2. select_type: SELECT 查询的类型.
  3. table: 查询的是哪个表
  4. partitions: 匹配的分区
  5. type: join 类型
  6. possible_keys: 此次查询中可能选用的索引
  7. key: 此次查询中确切使用到的索引.
  8. ref: 哪个字段或常数与 key 一起被使用
  9. rows: 显示此查询一共扫描了多少行. 这个是一个估计值.
  10. filtered: 表示此查询条件所过滤的数据的百分比
  11. extra: 额外的信息

select_type列说明:

  1. SIMPLE, 表示此查询不包含 UNION 查询或子查询
  2. PRIMARY, 表示此查询是最外层的查询
  3. UNION, 表示此查询是 UNION 的第二或随后的查询
  4. DEPENDENT UNION, UNION 中的第二个或后面的查询语句, 取决于外面的查询
  5. UNION RESULT, UNION 的结果
  6. SUBQUERY, 子查询中的第一个 SELECT
  7. DEPENDENT SUBQUERY: 子查询中的第一个 SELECT, 取决于外面的查询. 即子查询依赖于外层查询的结果.

type列说明

通常来说, 不同的 type 类型的性能关系如下:
ALL < index < range ~ index_merge < ref < eq_ref < const < system

类型

含义

system

表只有一行

const

表最多只有一行匹配,通用用于主键或者唯一索引比较时

eq_ref

每次与之前的表合并行都只在该表读取一行,这是除了system,const之外最好的一种,特点是使用=,而且索引的所有部分都参与join且索引是主键或非空唯一键的索引

ref

如果每次只匹配少数行,那就是比较好的一种,使用=或<=>,可以是左覆盖索引或非主键或非唯一键

fulltext

全文搜索

ref_or_null

与ref类似,但包括NULL

index_merge

表示出现了索引合并优化(包括交集,并集以及交集之间的并集),但不包括跨表和全文索引。

这个比较复杂,目前的理解是合并单表的范围索引扫描(如果成本估算比普通的range要更优的话

unique_subquery

在in子查询中,就是value in (select...)把形如“select unique_key_column”的子查询替换。

PS:所以不一定in子句中使用子查询就是低效的!

index_subquery 

同上,但把形如”select non_unique_key_column“的子查询替换

range 

常数值的范围

index

a.当查询是索引覆盖的,即所有数据均可从索引树获取的时候(Extra中有Using Index);

b.以索引顺序从索引中查找数据行的全表扫描(无 Using Index);

c.如果Extra中Using Index与Using Where同时出现的话,则是利用索引查找键值的意思;

d.如单独出现,则是用读索引来代替读行,但不用于查找

all

全表扫描

 

3、MySQL性能分析语句show profile

 

  1. Query Profiler是MYSQL自带的一种query诊断分析工具,通过它可以分析出一条SQL语句的性能瓶颈在什么地方。
  2. 通常我们是使用的explain,以及slow query log都无法做到精确分析,但是Query Profiler却可以定位出一条SQL语句执行的各种资源消耗情况,比如CPU,IO等,以及该SQL执行所耗费的时间等。不过该工具只有在MYSQL 5.0.37以及以上版本中才有实现。
  3. 默认的情况下,MYSQL的该功能没有打开,需要自己手动启动

语句使用:

select @@profiling; //结果1表示开启 0表示关闭(若关闭 可使用set profiling=1开启)

show variables like ‘%profil%’;

  • 通过以上两个语句均可以查看 当前session是否打开了profile功能.

  1. show profile 和 show profiles 语句可以展示当前会话(退出session后,profiling重置为0) 中执行语句的资源使用情况.
  2. show profiles :以列表形式显示最近发送到服务器上执行的语句的资源使用情况.显示的记录数由变量:profiling_history_size 控制,默认15条

可以查询指定语句的执行情况   例如Query_ID=139

 

3.show profile: 展示最近一条语句执行的详细资源占用信息,默认显示 Status和Duration两列

 

show profile 还可根据 show profiles 列表中的 Query_ID ,选择显示某条记录的性能分析(如上图的操作)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章