1.MySQL有哪些存储引擎(表类型)
- MyISAM
成熟稳定、快速读取,不支持事务,有表锁
- InnoDB
支持事务、外键、数据行锁,空间占用大,不支持全文索引
- HEAP
- BOB
- ARCHIVE
- CSV
常用的就MyISAM和InnoDB
2.myisam和innodb的区别
最大的区别就在于事务和锁上
- myisam不支持事务,适合频繁查询、小数据量、小并发的应用。表锁,不会出现死锁。
- innodb支持事务,适合插入、更新操作比较多的应用,行锁。
3.MySQL数据库,一天五万条左右的增量,预计运维三年,如何优化?
- 设计好数据库结构,允许数据冗余,减少join操作
- 选择合适的存储引擎与数据类型,适当的添加索引
- 配置MySQL读写分离,提高效率
- 在项目中添加二级缓存,ehcache、redis等
- 提高sql的执行效率,即sql优化
4.如何进行sql优化
1.选择合适的存储引擎
- myisam适合大量查询,很少写入的场景,查询速度非常快,因为是表锁,每次写入都会将整个表锁起来,其他进程无法对表进行操作,直到写入结束。
- innodb查询速度比myisam慢,但是支持行锁,允许事务,适合写入操作很频繁的场景。
2.优化字段的数据类型
选择合适的数据类型,存储数据长度越小的列操作越快,当然需要留够扩展空间。
比如一个表只会有几列数据,那么就没有必要用int来作为主键,要选择更小的smallint或tinyint。
如果不需要记录具体的时间,使用date比datetime要好很多。
3.为搜索字段添加索引
除主键外,也要给搜索字段添加索引,除非是一个大文本字段,那需要建立全文索引,但是5.6之前MySQL的innodb不支持全文索引。
4.避免使用seelct *
这会导致查询变得很慢,即使要查询数据库表全部的字段,也不要用 select *。
5.在某些情况下使用enum而不是varchar
enum是一个非常快、紧凑的类型,在底层上存储的是tinyint,在外部表现为字符串。
可以用于【性别、民族、国家、部门、状态】这种有固定值的字段,在这类字段上比varchar的表现要好。
6.尽量让表成为一张【固定长度静态表】
表内所有的字段都是【固定长度】的数据类型,则这张表会被视为【static或fixed-length 即固定长度静态表】,这种表效率会更高。
比如表里不存在【varchar、text、blob】,如果包含了则不会是【固定长度静态表】。
固定的长度很容易计算下一个数据的偏移量,因此查询会很快。如果字段不是定长,每次寻找下一条时,需要先找到主键。
固定长度的表更容易被缓存和重建,唯一的副作用是,固定长度会浪费一些空间,定长字段无论你用不用,都会占这么多空间。
7.尽量不要让字段处于null的状态
当一个字段没有被赋值的时候,是处于一个null的状态,null也是需要额外存储空间的,最关键的是在where比较时会拖垮sql效率,放弃索引,走全表扫描。
尽量给字段一个合适的默认值,来替代null的状态。
5.如何设计一个高并发的系统
- 数据库层面:合理安排事务隔离级别,sql语句优化、索引优化
- 尽量缓存,减少直接打到数据库的读操作
- 配置MySQL读写分离
6.锁的优化策略
- 读写分离
- 分段加锁
- 减少锁的持有时间
- 多线程尽量以相同的顺序去获取锁
以上并非绝对原则,要根据实际情况来定。比如不能将锁的粒度过于细化,否则可能会导致线程加锁、释放锁次数过多,效率反而不好。
7.索引的底层实现原理和优化
B+树,经过优化的B+树。
主要是在所有的叶子节点中,增加了指向下一个叶子节点的指针,因此innodb引擎建议大部份表使用默认的自增逐渐作为主索引。
8.什么情况下会导致:设置了索引,但是无法使用
- 以 % 开头的like语句
- or语句前后没有同时使用索引
- 数据类型出现隐式转换,比如varchar不加单引号可能会转为int
- 使用 != 或 <>
9.sql语句的优化
- 尽量避免全表查询,在where条件和order by中的字段上索引
- 在where条件中避免使用 != 或 <> 操作,这样会放弃索引,走全表扫描
- 避免对字段进行null值判断,这样会放弃索引,走全表扫描
- 避免使用or进行操作,很容易导致放弃索引,走全表扫描
- 避免在where中对字段进行表达式操作,这样会放弃索引,走全表扫描,例如
select id from t where num/2 = 100
select id from t where num = 100 * 2
- 避免在where中对字段进行函数操作,这样会放弃索引,走全表扫描,例如
select id from t where substring(name,1,3) = 'abc'
select id from t where datediff(day,createdate,'2005-11-30') = 0
select id from t where name like 'abc%'
select id from t where createdate >= '2005-11-30' and createdate < '2005-12-1'
- 索引不是越多越好,过多的索引会降低insert、update的效率,在插入和更新操作时,会重建索引。一般一张表不要超过6个索引,超过6个时,就要考虑一下有一些是不是没必要。
- 使用join来替代子查询
- 使用联合(UNION)来代替手动创建的临时表
10.优化MySQL整体的效率
他们四条从效果上第一条影响最大,后面越来越小
- sql语句和索引的优化
- 数据库表结构与引擎的优化
- 系统配置优化
- 硬件加配置!
11.MySQL中,索引、主键、唯一索引、联合索引的区别,对数据库性能有何影响?
索引(key或index)
索引是一种特殊文件(innodb数据表上的索引是表空间的一个组成部分),包含对数据表里所有记录的引用指针。
普通索引(关键字key或index定义的索引)唯一的任务就是加快对数据的访问速度。
普通索引允许出现重复的值。
唯一索引(UNIQUE)
唯一索引和索引的区别在一,唯一索引不允许出现数据重复。
主键(PRIMARY KEY)
主键是一种特殊的唯一索引,一张表只能有一个
联合索引 【 INDEX(columnA, columnB) 】
覆盖多个数据列的索引,列如 INDEX(columnA, columnB, columnC),这就是联合索引,比如电话簿里的名称和手机号是一对。
联合索引是有顺序的,支持a 、 a,b 、 a,b,c 3种组合进行查找,但不支持 b,c进行查找,当最左侧字段是常量引用时,索引就十分有效。
对数据库的影响
索引会加快查询速度,但是会降低插入、更新、删除的速度,因为需要额外的变更索引文件。
12.key和index的区别
- key是数据库的物理结构,有两层意义和作用,一个是约束(偏重于约束和规范数据库的结构完整性),第二个是索引(辅助查询用的)。
包括primary key, unique key, foreign key 等
- index是数据库的物理结构,只是辅助查询的,创建时会在另外的表空间(mysql中的innodb表空间)以一个类似于目录的结构存储。
包括前缀索引、全文本索引等
13. 外键和主键的区别
主键是本表的,外键是其他表的主键,一张表可以有多个外键,但是只能有一个主键
14.MySQL内连接、外连接区别
- 交叉连接 :交叉连接又叫笛卡尔积,是指不用任何条件,直接将一个表的所有记录和另一个表的所有记录挨个匹配。
- 内连接 :只有条件的交叉连接,根究条件筛选出合适的记录,内连接只连接匹配的行
- 外连接 :结果集不仅包含符合条件的行,还可以包含【左表、右表、两个表中所有的数据行】,空值用null表示,分表叫【左外连接、右外连接、全外连接】
15.mysql支持的分区类型
- RANGE分区:将数据划分为不同的范围,例如将一个表通过年份分为若个分区。
- LIST分区:通过与定义的列表值,对数据进行分割,按照list中的值分区。
- HASH分区:通过对表中一个或多个字段的hash进行分区,例如建立一个对标主键进行分区的表。
- KEY分区:上面Hash模式的一种延伸,这里的Hash Key是MySQL系统产生的。
16.什么是事务
事务(transaction)是作为一个单元的一组有序数据库操作。
如果组里所有的操作都成功,则事务成功,提交事务,所有操作将推广至所有其他数据库进程。
有一个操作失败,则事务失败,进行事务回滚,该事务的所有操作都被当作没进行过。
17.事务四种隔离级别
- Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
- Repeatable read (可重复读):可避免脏读、不可重复读的发生。
- Read committed (读已提交):可避免脏读的发生。
- Read uncommitted (读未提交):最低级别,任何情况都无法保证。