8.MVCC是什么?
MVCC是多版本并发控制,在很多情况下避免加锁,大都实现了非阻塞的读操作,写操作也只锁定必要的行。
InnoDB的MVCC通过在每行记录后面保存两个隐藏的列来实现,这两个列一个保存了行的创建时间,一个保存行的过期时间。不过存储的不是实际的时间值,而是系统版本号,每开始一个新的事务系统版本号都会自动递增,事务开始时刻的系统版本号作为事务的版本号,用来和查询到的每行记录的版本号进行比较。
9.谈一谈InnoDB
InnoDB是MySQL的默认事务型引擎,用来处理大量短期事务。InnoDB的性能和自动崩溃恢复特性使得它在非事务型存储需求中也很流行,除非有特别的原因,否则应该优先考虑InnoDB。
InnoDB的数据存储在表空间中,表空间由一系列数据文件组成。MySQL4.1后的InnoDB可以将每个表的数据和索引放在单独的文件中。
InnoDB表是基于聚簇索引建立的,InnoDB的索引结构和其他存储引擎有很大不同,聚簇索引对主键查询有很高的性能,不过他的二级索引中必须包含主键列,所以如果主键很大的话,其他所有索引都会很大,因此如果表上索引较多的话主键应当尽可能小。
InnoDB 的存储均存储在B+树的叶子节点上的,可以将数据和索引⽂件从⼀个平台复制到另⼀个平台。
InnoDB 内部做了很多优化,包括从磁盘读取数据时采⽤的可预测性预读,能够⾃动在内存中创建加速读操作的⾃适应哈希索引,以及能够加速插⼊操作的插⼊缓冲区等。
10.谈谈MyISAM
MyISAM 是MySQL5.1版本之前的默认存储引擎。
MyISAM 提供了大量的特性,包括全文索引、压缩、空间函数等,但是不支持事务和行锁,最大的缺陷就是崩溃后无法安全恢复。对于只读的数据或者表比较小、可以忍受修复操作的情况仍然可以使用MyISAM 。
MyISAM 用三个文件表示每个表:
格式文件——存储表结构的定义(mytable.frm)
数据文件——存储行的内容(数据)(mytable.MYD)
索引文件——存储表上索引(mytable.MYI)
MyISAM 对整张表进行加锁,读取时会对需要读到的所有表加共享锁,写入时则对表加排他锁。但是在表有读取查询的同时,也支持并发往表中插入新记录。MyISAM 可以被压缩,节省存储空间,并且可以转换为只读表,提高检索效率。
11.谈谈Memory
如果需要快速访问数据,且这些数据不会被修改,重启以后丢失也没有关系,那么使用Memory是很有用的。Memory表至少要比MyISAM 快一个数量级,因为所有的数据都存在内存,不需要磁盘IO,Memory表的结构在重启后会保留,但数据会丢失。
Memory支持哈希索引,因此查找速度极快,虽然很快但还是无法取代传统的基于磁盘的表,Memory表使用表级锁,因此并发写入性能较低。
12.查询的执行流程
- 客户端发送一条查询给服务器
- 服务器先检查查询缓存,如果命中了缓存则立刻返回存储在缓存中的结果,否则进入下一阶段
- 服务器进行SQL解析、预处理,再由优化器生成对应的执行计划
- MySQL根据优化器生成的执行计划,调用存储引擎的API来执行查询
- 将结果返回给客户端
13.VARCHAR和CHAR的区别
VARCHAR 用于存储可变字符串,当插入的长度小于定义的长度时,插入多长就存多长;CHAR长度固定,当插入的长度小于定义的长度时,用空格填充。
CHAR存取速度比VARCHAR要快,但同时由于他的长度固定,也会占据多余空间。
varchar的最大有效长度由最大行大小和使用的字符集确定;而CHAR最多能存放的字符个数255,与编码无关。
14.DATETIME和TIMESTAMP的区别
DATETIME能保存大范围的值,从1001-9999,精度为秒。把日期和时间封装到了一个整数中,与时区无关,使用8字节存储空间。
TIMESTAMP只使用4字节的存储空间,范围比DATETIME小得多,只能表示1970-2038年,并且依赖时区。
15.数据类型有哪些优化策略
- 更小的通常更好
一般情况下,尽量使用可以正确存储数据的最小数据类型,更小的数据类型通常也更快,因为他们占用更少的磁盘、内存和CPU缓存。 - 尽可能简单
简单数据类型的操作通常需要更少的CPU周期。例如整数比字符操作代价更低,因为字符集和校对规则使字符相比整型更复杂。应该使用MySQL的内建类型date、time和datetime,而不是字符串来存储日期和时间;另一点应该使用整型存储IP地址。 - 尽量避免NULL
通常情况下,最好指定列为NOT NULL,除非需要存储NULL值。因为如果查询中包含可为NULL的列对MySQL来说更难优化,可为NULL的列使索引、索引统计和值比较都更复杂,并且会使用更多存储空间。
当可为NULL的列被索引时,每个索引记录需要一个额外字节,再MyISAM中还可能导致固定大小的索引变成可变大小的索引。如果计划在列上建索引,就应该避免设计成为可NULL的列。