一、MySQL架构介绍
1. MySQL简介
一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司。
一种关联数据库管理系统,将数据保存在不同的表中,而不是将所有数据放在一个大仓库里,这样可以增加速度并提升灵活性。
开源的,无需支付额外费用。
支持大型的数据库,可以拥有长千万条记录的大型数据库。32位操作系统最大可支持4GB,64位操作系统最大的表文件为8TB。
使用标准的SQL数据语言形式。
可以允许于多个系统上,支持多种语言。例如:C、C++、Python、Java、Perl、PHP、Eiffel、Ruby等。
对PHP有很好的支持。
可定制,采用GPL协议,可以通过修改源码来开发自己的MySQL系统。
2. Linux安装MySQL
略
3. MySQL配置文件
1) 二进制日志 log-bin
主要应用于主从复制,记录数据库增量日志,用于主从复制。
2)错误日志 log-error
默认是关闭的,记录严重的警告和错误信息,每次启动和关闭的详细信息等。
3)查询日志 log
默认是关闭的,记录查询的sql语句,如果开启会降低mysql整体性能,因为记录日志是需要消耗系统资源的。可以通过设置阈值,例如记录所有超过五秒以上的查询sql语句。
4)数据文件
文件 | 功能 |
---|---|
frm文件 | 存放表结构 |
myd文件 | 存放表数据 |
myi文件 | 存放表索引 |
5) 如何配置
操作系统 | 文件 |
---|---|
windows | my.ini |
linux | /etc/my.cnf |
4.MySQL的逻辑架构介绍
1)总体概览
和其他数据库相比,MySQL有点与众不同,它得架构可以在多种不同场景中应用并发挥良好作用。主要体现在存储引擎得架构上,插件式得存储引擎架构将查询处理和其他得系统任务以及数据的存储提取相分离。这种架构可以根据业务的需求和实际需要选择合适的存储引擎。
连接层 ⇒ 服务层 ⇒ 引擎层 ⇒ 存储层
5. MySQL存储引擎
1) 查看命令
mysql>show variables like '%storage_engine%';
2) MyISAM和InnoDB区别
对比项 | MyISAM | InnoDB |
---|---|---|
主外键 | 不支持 | 支持 |
事务 | 不支持 | 支持 |
行表锁 | 表锁,即使操作一条记录也会锁住整个表,不适合高并发场景 | 行锁,操作时只锁定某一行,不对其它行有影响,适合高并发场景 |
缓存 | 只缓存索引,不缓存数据 | 不仅缓存索引还缓存真实数据,对内存要求较高,而且内存大小对性能有决定性的影响 |
表空间 | 小 | 大 |
关注点 | 性能 | 事务 |
二、索引优化分析
1.SQL性能下降的原因
1) 查询语句写的没眼看
连接,子查询,没有用到索引,或没有建立索引。
2) 索引失效
建立了索引,但是没有用到。
单值索引: 只给某一个字段建立索引,应用于频繁进行单条件的查询语句,例如:
select * from user where name = "?";
create index inx_user_name on user(name); //建立单值索引
在建立索引后,索引字段会进行排序,大幅提升查询速度。
复合索引: 给某些字段建立复合索引,应用于频繁进行多条件查询语句,例如:
select * from user where name = "?" and email = "?";
create index idx_user_nameEmail on user(name,email); //建立复合索引
3) 关联查询太多join (设计缺陷或不得已的需求)
join越少越好。
4)服务器调优以及各个参数设置
例如缓冲、线程数等。
2.常见通用的join查询
1) SQL执行顺序
2)七种join图
先上两张测试表
- 第一种
SELECT * FROM emp a INNER JOIN dept b on a.dept_id = b.id
执行结果:
- 第二种
SELECT * from emp a left join dept b on a.dept_id = b.id
执行结果:
- 第三种
SELECT * from emp a RIGHT join dept b on a.dept_id = b.id
执行结果:
- 第四种
SELECT * from emp a left join dept b on a.dept_id = b.id where b.id is null
执行结果:
-
第五种
sql同第四种,修改left ==> reight -
第六种
select * from emp a left join dept b on a.dept_id = b.id union select * from emp a right join dept b on a.dept_id = b.id
执行结果:
- 第七种
select * from emp a left join dept b on a.dept_id = b.id where b.id is null union select * from emp a right join dept b on a.dept_id = b.id where a.dept_id is null
执行结果:
3. 索引
1)索引是什么
MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。
在数据本身之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式指向数据,这样就可以在这些数据结构上实现高级查找算法。下图是一种可能的索引方式示例(二叉查找树):
为了加快Col2的查找,可以维护一个类似于右边的二叉查找树,每个节点分别包含索引键值和一个只想对应数据记录物理地址的指针,这样就可以运用二叉查找在一定的复杂度内获取到相应的数据,从而快速的检索出符合条件的记录。
适合建立索引的字段是不常进行删改操作且经常查询的字段。
一般来说索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储在磁盘上。
我们平常所说的索引,如果没有特别指明,都是指B树(多路搜索树,并不一定是二叉树)结构组织的索引。其中聚集索引,次要索引,复合索引,前缀索引,唯一索引默认都是B+树索引,统称索引。当然,除了B+树这种类型的索引 之外,还有哈希索引 ⇒ hash index等。
2)索引优势和劣势
优势:
- 类似于大学图书馆建立书目索引,提高数据检索效率,降低数据库的IO成本。
- 通过索引对数据进行排序,降低数据排序的成本,降低了CPU的消耗。
劣势:
- 索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引也是要占用空间的。
- 虽然索引大大提高了查询速度,同时也会降低更新表的速度,如INSERT,UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息。
- 索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引。
3)索引分类
类别 | 说明 |
---|---|
单值索引 | 即一个索引只包含单个列,一个表可以有多个单列索引 |
唯一索引 | 索引列的值必须唯一,但允许空值 |
复合索引 | 即一个索引包含多个列 |
4)索引基本语法
- 添加索引
//添加主键索引,唯一且不能为NULL
alter table table_name add primary key (column_list);
//添加唯一索引,唯一可为NULL
alter table table_name add unique index_name (column_list);
//添加普通索引,索引值可出现多次
alter table table_name add index index_name (column_list);
//添加全文索引
alter table table_name add fulltext index_name (column_list);
- 删除索引
drop index index_name on table_name
- 查看索引
show index from table_name
5) 创建索引条件
- 主键自动建立唯一索引。
- 查询中与其他表关联的字段,外键关系应该建立索引。
- 频繁作为查询条件的字段应该建立索引。
- 单值/复合索引的选择问题,高并发下倾向于创建复合索引。
- 查询中排序字段,排序字段若通过索引去访问将大大提高排序速度。
- 查询中同级或者分组的字段要建立索引。
- 记录太少不需要建立索引。
- 频繁更新的字段不适合建立索引。
- 数据重复且分布平均的表字段不适合建立索引。
- where条件里用不到的字段不适合创建索引。
4.sql性能分析
1)MySQL常见瓶颈
- CPU:CPU饱和时一般发生在数据装入内存或从磁盘上读取数据。
- IO:磁盘I/O瓶颈发生在装入数据远大于内存容量的时候
- 服务器硬件的性能瓶颈:top,free,iostat和vmstat来查看系统性能状态。
2)Explain关键字
使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,查看MySQL是如何处理你的SQL语句的,从而得知你的查询语句或是表结构的性能瓶颈。
- 作用
- 表的读取顺序
- 数据读取操作的操作类型
- 哪些所以可以使用
- 哪些索引被实际使用
- 表之间的引用
- 每张表有多少行被优化器查询
- 怎么玩
explain + sql
执行结果:
表头解释:
- id
select查询的序列号,包含一组数字,表示查询中执行select子句或操作表的顺序。id相同,执行顺序由上至下;如果是子查询,id序号会递增,id值越大表明优先级越高,越早被执行;若有相同有不同,先执行优先级高的,在按照顺序执行优先级相同的。
- select_type
- table
表明当前行是哪张表的查询。
- type
显示的是访问类型,是较为重要的一个性能直表。
类型 | 含义 |
---|---|
system | 表只有一行记录(等于系统表),这是const类型的特例,平时不会出现,这个也可以忽略不计。 |
const | 表示通过索引一次就找到了,const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快将主键置于where列表之中,MySQL就能将该查询转换为一个常量。 |
eq_ref | 唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描。 |
ref | 非唯一性索引扫描,返回匹配某个单独值得所有行。本质上也是一种索引访问,它返回所有匹配某个单独值得行,然而,可能存在多个符合条件的行,所以他应该属于查找和扫描的混合体。 |
range | 只检索给定范围的行,使用一个索引来选择行。Key列显示使用了哪个索引。一般出现于执行where、between、<、>、in等查询语句时。这种范围扫描索引比全表扫描要好,因为它只需要开始于索引的某一点,而结束于另一点,不需要进行全表扫描。 |
index | Full Index Scan, index与ALL区别为index类型只遍历索引树。这通常比ALL快,因为索引文件通常比数据文件小。(也就是说虽然ALL和index都是读全表,但index是从索引中读取的,而ALL是从磁盘中读取的) |
ALL | 无索引情况下的全表扫描 |
结果值从最好到最坏依次是:
system ⇒ const ⇒ eq_ref ⇒ ref ⇒ range ⇒ index ⇒ ALL
一般来说,得保证查询至少达到range级别,最好能达到ref。
- possible_keys和key
用于判断是否使用了索引(即索引是否失效)且在多个索引竞争的情况下MySQL到底使用了哪个索引。
字段名 | 含义 |
---|---|
possible_keys | 显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用。 |
key | 实际被使用的索引,如果为NULL,则表明没有索引被使用。查询中若使用了覆盖索引,则该索引仅出现在key列表中。 |
- key_len
表示索引中使用的字节数,可通过该列计算查询中使用索引的长度。在不损失精度的情况下,长度越少越好。key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出来的。
- ref
显示索引的哪一列被使用了,如果可能的话,是一个常数。即哪些列或常量被用于查找索引列上的值 。
- rows
根据表统计信息以及索引选用情况,大致估算出找到所需记录多需要读取的行数。
- Extra
三、查询截取分析
四、MySQL锁机制
五、主从复制
六、常用SQL语句(补充)
select * from dept a,emp b where a.id = b.id;
select * from dept where id between 30 and 60;
select * from dept where id in (1,2,6);
desc table_name; //查询表结构