/images/hugo/avatar.png

25 MYSQL Memory 存储引擎

什么时候使用 Memory 存储引擎

1. 索引组织对比

假设有以下的两张表 t1 和 t2,其中表 t1 使用 Memory 引擎, 表 t2 使用 InnoDB 引擎。

1
2
3
4
create table t1(id int primary key, c int) engine=Memory;
create table t2(id int primary key, c int) engine=innodb;
insert into t1 values(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);
insert into t2 values(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(0,0);

1.1 innodb 组织形式

InnoDB 表的数据放在主键索引树上,主键索引是 B+ 树。所以表 t2 的数据组织方式如下图所示:主键索引上的值是有序存储的。

24 临时表

什么时候会使用临时表

1. 临时表

1.1 临时表跟内存表

  1. 内存表,指的是使用 Memory 引擎的表,建表语法是 create table … engine=memory。这种表的数据都保存在内存里,系统重启的时候会被清空,但是表结构还在。除了这两个特性看上去比较“奇怪”外,从其他的特征上看,它就是一个正常的表。
  2. 而临时表,可以使用各种引擎类型 。如果是使用 InnoDB 引擎或者 MyISAM 引擎的临时表,写数据的时候是写到磁盘上的。当然,临时表也可以使用 Memory 引擎

1.2 临时表的特征

/images/mysql/MySQL45%E8%AE%B2/temporary_table_feature.png

23 join

join 语句是怎么执行的

1. 实验环境

1
2
3
4
5
CREATE TABLE `t2` (  `id` int(11) NOT NULL,  `a` int(11) DEFAULT NULL,  `b` int(11) DEFAULT NULL,  PRIMARY KEY (`id`),  KEY `a` (`a`)) ENGINE=InnoDB;

drop procedure idata;delimiter ;;create procedure idata()begin  declare i int;  set i=1;  while(i<=1000)do    insert into t2 values(i, i, i);    set i=i+1;  end while;end;;delimiter ;call idata();

create table t1 like t2;insert into t1 (select * from t2 where id<=100)

这两个表都有一个主键索引 id 和一个索引 a,字段 b 上无索引。存储过程 idata() 往表 t2 里插入了 1000 行数据,在表 t1 里插入的是 100 行数据。

22 常见语句的执行逻辑

count,order by 都是怎么执行的

1. count

在不同的 MySQL 引擎中,count(*) 有不同的实现方式:

  • MyISAM: 把一个表的总行数存在了磁盘上,在没有筛选条件时,count(*) 可以直接返回
  • Innodb: 需要把数据一行一行地从引擎里面读出来,然后累积计数。

由于 Innodb 事务是基于 MVCC 的多版本控制机制实现的,每一行记录都要判断自己是否对这个会话可见,因此对于 count(*) 请求来说,InnoDB 只好把数据一行一行地读出依次判断,可见的行才能够用于计算“基于这个查询”的表的总行数。对于 count(*) 遍历主键索引和二级索引得到的结果逻辑上是一致的。MySQL 优化器会找到最小的那棵树来遍历。在保证逻辑正确的前提下,尽量减少扫描的数据量,是数据库系统设计的通用法则之一。

21 MySQL 表复制

怎么最快的复制一张表

1. 在两张表中拷贝数据

如果可以控制对源表的扫描行数和加锁范围很小的话,我们简单地使用 insert … select 语句即可实现。当然,为了避免对源表加读锁,更稳妥的方案是先将数据写到外部文本文件,然后再写回目标表。这时,有三种常用的方法。