逻辑架构图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
执行顺序:
- FROM(将最近的两张表,进行笛卡尔积)---VT1(VT--->virtual table 虚表)
- ON(将VT1按照它的条件进行过滤)---VT2
- LEFT JOIN(保留左表的记录)---VT3
- WHERE(过滤VT3中的记录)--VT4…VTn (根据where的条件个数来看 一个条件产生一个虚表)
- GROUP BY(对VT4的记录进行分组)---VT5
- HAVING(对VT5中的记录进行过滤)---VT6
- SELECT(对VT6中的记录,选取指定的列)--VT7
- ORDER BY(对VT7的记录进行排序)--VC8(游标)
- 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列,分别是id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra,下面对这些字段进行解释:
- id: SELECT 查询的标识符. 每个 SELECT 都会自动分配一个唯一的标识符.
- select_type: SELECT 查询的类型.
- table: 查询的是哪个表
- partitions: 匹配的分区
- type: join 类型
- possible_keys: 此次查询中可能选用的索引
- key: 此次查询中确切使用到的索引.
- ref: 哪个字段或常数与 key 一起被使用
- rows: 显示此查询一共扫描了多少行. 这个是一个估计值.
- filtered: 表示此查询条件所过滤的数据的百分比
- extra: 额外的信息
select_type列说明:
- SIMPLE, 表示此查询不包含 UNION 查询或子查询
- PRIMARY, 表示此查询是最外层的查询
- UNION, 表示此查询是 UNION 的第二或随后的查询
- DEPENDENT UNION, UNION 中的第二个或后面的查询语句, 取决于外面的查询
- UNION RESULT, UNION 的结果
- SUBQUERY, 子查询中的第一个 SELECT
- 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
- Query Profiler是MYSQL自带的一种query诊断分析工具,通过它可以分析出一条SQL语句的性能瓶颈在什么地方。
- 通常我们是使用的explain,以及slow query log都无法做到精确分析,但是Query Profiler却可以定位出一条SQL语句执行的各种资源消耗情况,比如CPU,IO等,以及该SQL执行所耗费的时间等。不过该工具只有在MYSQL 5.0.37以及以上版本中才有实现。
- 默认的情况下,MYSQL的该功能没有打开,需要自己手动启动。
语句使用:
select @@profiling; //结果1表示开启 0表示关闭(若关闭 可使用set profiling=1开启)
show variables like ‘%profil%’;
- 通过以上两个语句均可以查看 当前session是否打开了profile功能.
- show profile 和 show profiles 语句可以展示当前会话(退出session后,profiling重置为0) 中执行语句的资源使用情况.
- show profiles :以列表形式显示最近发送到服务器上执行的语句的资源使用情况.显示的记录数由变量:profiling_history_size 控制,默认15条
可以查询指定语句的执行情况 例如Query_ID=139
3.show profile: 展示最近一条语句执行的详细资源占用信息,默认显示 Status和Duration两列
show profile 还可根据 show profiles 列表中的 Query_ID ,选择显示某条记录的性能分析(如上图的操作)