1 数据库三大范式
- 第一范式:每个列都不可以再拆分
- 第二范式:在第一范式的基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分
- 第三范式:在第二范式的基础上,非主键列只依赖于主键,不依赖于其他非主键
2 mysql有关权限的表有哪些
- mysql服务器通过权限表来控制用户对数据的访问,权限表存放在mysql数据库里,由mysql_install_db脚本初始化。这些权限表分别为:user,db,table_priv,columns_priv和host。下面分别介绍以下这些表的结构和内容:
1. user权限表:记录允许连接到服务器的用户账号信息,里面的权限是全局级的
2. db权限表:记录各个账号在各个数据库上的操作权限
3. table_priv权限表:记录数据表级的操作权限
4. columns_priv权限:记录数据列级的权限
5. host:配合db权限表对给定主机上数据库级操作权限做更加详细的控制。这个权限表不受GRANT和REVOKE语句的影响
3 mysql的binlog有几种录入方式
- 有三种方式:statement,row和mixed
1. statement:在statement模式下,每一条会修改数据的sql都会记录在binlog中。不需要记录每一行的变化,减少了binlog日志量,节约了IO,提升性能。由于SQL的执行是有上下问的,因此在保存的时候需要保存相关信息,同时还有一些使用了函数之类的语句无法被记录复制
2. row:在row级别下,不记录sql语句上下文相关信息,仅保存哪条记录被修改。记录单元为每一行的改动,基本可以全部记录下来很多操作,会导致大量行的改动(比如alter table),因此这种模式的文件保存的信息太多,日志量太大
3. mixed:一种折中的方案,普通操作使用statement记录,无法使用statement的时候使用row
- 此外,新版的mysql对row级别做了一些优化,当表结构发生拜年话的时候,会记录语句而不是逐行记录
4 mysql数据类型
- 整数类型:
1. tinyint:很小的整数(8个二进制位)
2. smallint:小的整数(16个二进制位)
3. mediumint:中等大小的整数(24个二进制位)
4. int:普通大小的整数(32个二进制位)
5. 说明:
- 整数类型,包括tinyint,smallint,mediumint,int,bigint。分别代表1个字节,2个字节,3个字节,4个字节,8个字节整数。任何整数类型都可以加上UNSIGNED属性,表示数据是无符号的
- 长度:整数类型可以被指定长度,例如:int(11)表示长度为11的整数。长度在大多数场景下是没有意义的,他不会限制值的合法范围,只会印象显示字符的个数,而且需要和unsigied zerofill属性配合使用才由意义
- 例子:假定类型设定为int(5),属性为unsigned zerofill,如果用户插入的数据为12,你怎么数据库实际存储值为00012
- 浮点数类型:
1. float:单精度浮点数
2. double:双精度浮点数
3. decimal(m, d):压缩严格的定点数
4. 说明:
- 实数类型,包括float,double,decimal。decimal可以用于存储比bigint还大的整型,能存储精确的小数
- float和double是有取值范围的,并支持使用标准的浮点近似计算
- 计算时float和double相比decimal效率更高一些,decimal可以理解为用字符串进行处理
- 日期类型:
1. year:1901--2155
2. time:-838:59:59--838:59:59
3. date:1000-01-01 00:00:00--9999-12-31
4. datetime:1000-01-01 00:00:00--9999-12-31 23:59:59
5. timestamp:19700101 00:00:01--2038-01019 03:14:07
6. 说明:
- 日期类型和事件类型尽量使用timestamp,空间效率高于datetime
- 用整数保存时间戳经常不方便处理
- 如果需要存储微妙,可以使用bigint存储
- 文本类型:
1. char(M):M为0-255之间的整数
2. varchar(M):M为0-65535之间的整数
3. tinyblob:允许长度为0-255字节
4. blob:允许长度为0-65535字节
5. mediumblob:允许长度为0-167772150字节
6. longblob:允许长度为4294967295字节
7. tinytext:允许长度为0-255字节
8. text:允许长度为0-65535字节
9. mediumtext:允许长度为0-167772150字节
10. longtext:允许长度为0-4294967295字节
11. varbinary(M):允许长度为0-M个字节的变长字节字符串
12. binary(M):允许长度为0-M个字节的定长字节字符串
13. 说明:
- 字符串类型包括varchar,char,text,blog。varchar用于存储可变长字符串,他比定长字符串更节省空间。
- varchar需要使用额外的1或2个字节存储字符串长度。列长度小于255字节时,使用1字节表示,否则使用2字节表示
- varchar存储的内容长度超过设置的长度时,内容会被截断
- char是定长的,根据定义的字符串长度分配足够的空间
- char会根据需要使用空格进行填充比较方便
- char适合存储很短的字符串,或者所有制都接近同一个长度
- char存储的内容超过设置的长度时,内容同样会被截断
14. 使用策略:
- 对于经常变更的数据来说,char比varchar更好,因为char不容易产生碎片
- 对于非常短的列,char比varchar在存储空间上更有效率
- 使用时要注意只分配需要的空间,更长的列,排序时会消耗更多的内存
- 尽量避免使用text/blog类型,查询时会使用临时表,导致严重的性能开销
- 其他:
5 存储引擎区别
1. 存储引擎:mysql中的数据,索引以及其他对象是如何存储的,是一套文件系统的实现
2. 常用的存储引擎有:
- innodb:innodb提供了对数据库ACID事务的支持。并且还提供了行级锁和外键约束。他的设计目标就是提供处理大数据容量的存储系统
- myisam:不提供十五支持,也不支持行级锁和外键
3. 区别:
- 存储结构:
1. myisam:每张表被存放在三个文件:frm-表格定义,myd-数据文件,myi-索引文件
2. innodb:所有的表都保存在同一个数据文件中(也可能是多个文件,或者独立的表空间文件)。innodb表的大小只受限于操作系统文件的大小,一般为2GB
- 存储空间:
1. myisam:myisam可以被压缩,存储空间较小
2. innodb:innodb的表需要更多的内存和存储,他会在主内存中建立专门的缓冲池用于高速缓冲数据和索引
- 可移植性,备份以及恢复:
1. myisam:myisam的数据是以文件的形式存储,所以在跨平台的数据中一种会很方便。在备份和恢复时可以单独针对某个表进行操作
2. innodb:免费的方案可以是拷贝数据文件,备份binlog,或者使用mysqldump,在数据量达到几十G的时候就相对痛苦了
- 文件格式:
1. myisam:数据和索引时分别存储的
2. innodb:数据和索引是集中存储的
- 记录存储顺序:
1. myisam:数据按记录插入顺序保存
2. innodb:按主键大小有序存储
- 外键:
1. myisam:不支持
2. innodb:支持
- 事务:
1. myisam:不支持
2. innodb:支持
- 锁支持:锁是避免资源竞争的一个机制,mysql锁对用户几乎是透明的
1. myisam:表级锁
2. innodb:表级锁,行级锁,锁定力度小,并发能力高
- SELECT:
- INSERT,UPDATE,DELETE:
- SELECT count(*):
1. myisam:myisam更快,因为myisam内部维护了一个计数器,可以直接调取
- 索引的实现方式
1. myisam:B+树索引,myisam是堆表
2. innodb:B+树索引,innodb是索引组织表
- 哈希索引:
1. myisam:不支持
2. innodb:支持
- 全文索引:
1. myisam:支持
2. innodb:不支持
6 myisam索引和innodb索引区别
- innodb索引是聚簇索引,myisam索引是非聚簇索引
- innodb的主键索引的叶子节点存储行数据,主键索引非常高效
- myisam索引的叶子节点存储的是行数据地址,需要再一次寻址才能得到数据
- innodb是非主键索引的叶子节点存储的是主键和其他带索引的列数据
7 innodb的四大特性
- 插入缓冲
- 二次写
- 自适应哈希索引
- 预读
8 存储引擎选择
- 如果没有特别的需求,使用默认innodb即可
- 以读写插入为主的应用程序使用myisam
- 保证数据完整性,并发量高,支持事务和外键,使用innodb
9 索引优缺点
- 优点:
1. 增加检索速度
2. 通过使用索引,可以在查询过程中,使用优化隐藏器,提高系统性能
- 缺点:
1. 创建索引需要消耗时间,对表中数据进行增删查改时也需要动态维护,降低增删改的效率
2. 索引需要额外的物理空间开销
10 索引使用场景
- where
- order by
- 当使用order by将查询结果按照某个字段排序时,如果该字段没有建立索引,那么执行计划将会查询出所有数据然后使用外部排序(将数据从磁盘分批读入内存使用内部排序,最后合并排序结果),这个操作非常影响性能,因为需要将查询涉及到的所有数据从磁盘读到内存,单条数据过大或者数据量过多时都会影响效率
- 建立索引之后,索引本身有序,因此按照索引顺序和映射关系逐条读出数据即可。而且如果分页的话,那么只需读取索引表某个范围内的索引对应的数据。
join
- 对join的on涉及的字段建立索引能够提高效率
11 索引覆盖
- 如果要查询的字段都建立过索引,那么存储引擎会直接在索引表中查询而不会访问原始数据,这叫索引覆盖
12 索引有哪几种类型
- 主键索引:数据列不允许重复,不允许为null,一个表只能有一个主键
- 唯一索引:数据列不允许重复,允许为null,一个表允许多个列创建唯一索引
- 普通索引:基本索引类型没有唯一性限制,允许为null
- 全文索引:是目前搜索引擎使用的一种关键技术
13 索引的数据结构
14 索引原理
15 索引算法
16 索引设计原则
- 适合索引的列是出现在where子句中的列,或者连接子句中的列
- 基数比较小的列,索引效果较差,没必要建立索引
- 不要过度索引。索引需要额外的磁盘空间,并降低写操作的性能。在修改表内容的时候,索引会进行更新甚至重构,索引列越多,这个时间就越长。所以之保持需要的索引有利于查询即可
17 建立索引原则
- 最左前缀原则,范围查询停止匹配
- 较频繁作为查询条件的字段才去创建索引
- 跟新频繁字段不适合创建索引
- 若是不能有小区分数据的列,不适合做索引列,比如性别,最多只有三种,区分度太低
- 尽量使用扩展索引,不要新建索引
- 定义有外键的数据列一定要建立索引
- 对于那些查询中很少设计的列,重复值比较多的列不要建立索引
- 对于定义为text,image和bit的数据类型的列不要建立索引
- 非空字段,应该指定为not null,除非你想存储null。在mysql中,含有空值的列很难进行查询优化,因为它们使得索引,索引的统计信息以及比较运算更加复杂。应该用0或者特殊值或者空串来代替空值
- 取值离散大的字段,字段各个值之间差异程度大的列放到联合索引的前面,可以通过count函数来查看字段的差异值,唯一值越多字段离散程度越高
18 百万级别或以上数据如何删除
- 先删索引
- 再删无效数据
- 重新创建索引
19 前缀索引
20 创建索引三种方式
- 创建表时就建立索引
- 使用alter table来增加索引
- 使用create index创建索引
- 删除索引
21 hash索引和B+树索引比较
22 在B+树上满足聚簇索引和覆盖索引的时候不需要回表查询数据吗
- 在B+数索引中,叶子节点可能存储了当前key的值,也可能存储了当前key的值以及整行的数据,这就是聚簇索引与非聚簇索引。在innodb中,只有主键索引是聚簇索引,如果没有主键,则挑选一个唯一键作为聚簇索引。如果没有唯一键,则隐式生成一个键来建立聚簇索引
- 当查询聚簇索引时,在对应的叶子节点,可以获取到整行数据,因此不需要再回标查询
23 合适使用聚簇索引与非聚簇索引
- 列经常被分组排序:
- 使用聚簇索引:应该
- 使用非聚簇索引:应该
- 返回某范围内的数据:
- 使用聚簇索引:应该
- 使用非聚簇索引:不应该
- 一个或极少不同的值:
- 使用聚簇索引:不应该
- 使用非聚簇索引:不应该
- 小数目的不同值:
- 使用聚簇索引:应该
- 使用非聚簇索引:不应该
- 大数目的不同值:
- 使用聚簇索引:不应该
- 使用聚簇索引:应该
- 频繁更新的列:
- 使用聚簇索引:不应该
- 使用非聚簇索引:不应该
- 外键列:
- 使用聚簇索引:应该
- 使用非聚簇索引:应该
- 主键列:
- 使用聚簇索引:应该
- 使用非聚簇索引:不应该
- 频繁修改索引列:
- 使用聚簇索引:不应该
- 使用非聚簇索引:应该
24 非聚簇索引一定会回表查询吗
- 不一定,这涉及到查询语句所以要求的字段是否全部都命中了索引,如果全部命中了索引,那么就不必再回表查询
- 比如:在年龄上查询了索引,当进行select age查询时,在索引的叶子节点上已经包含了age信息,那么变不会再回表查询了
25 事务的定义
26 mysql锁
- 当数据库有并发事务的时候,可能会产生数据的不一致,这时候需要一些机制来保证访问的次序,锁机制就是这样的一个机制
27 隔离级别和锁的关系
- 在读未提交级别下,读取数据不需要加共享锁,这样就不会跟被修改的数据上的排他锁冲突
- 在读已提交级别下,读取数据操作需要加共享锁,但是在语句执行完之后释放共享锁
- 在可重复读级别下,读操作需要加共享锁,但是在事务提交之前不是放共享锁,也就是必须等待事务执行完毕之后才释放共享锁
- 序列化时限制性最强的隔离级别,该隔离级别锁定整个范围的键,并一直持有锁,直到事务完成
28 按照锁的粒度分数据库锁有哪些?锁机制与innodb锁算法
- 在关系型数据库中,按照锁的粒度将锁分为行级锁,表级锁和页级锁
- myisam和innodb存储引擎使用的锁:
- myisam采用表级锁
- innodb支持行级锁和表级锁,默认为行级锁
- 页级锁,表级锁,行级锁对比:
- 页级锁:
- 页级锁是mysql中锁定粒度介于行级锁和表级锁之间的一种锁。表级锁速度快但冲突多,行级锁冲突少但速度慢。所以折中有了页级锁,一次锁定相邻的一组记录
- 特点:开销和加锁时间介于表级锁和行级锁之间。会出现死锁,锁定粒度介于表级锁和行级锁之间,并发度一般
- 表级锁:
- 表级锁是mysql中锁定粒度最大的一种锁。表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分mysql引擎支持。最常使用的myisam和innodb都支持表级锁。表级锁分为共享锁和排他锁
- 特点:开销小,枷锁快,不会出现死锁,锁定粒度大,发生锁冲突概率最高,并发度最低
- 行级锁:
- 行级锁是mysql中锁定粒度最细的一种锁,表示只针对当前操作的行加锁。行级锁能大大减少数据库操作的冲突。加锁粒度最小,加锁开销最大。行级锁分为共享锁和排他锁
- 特点:开销大,加锁慢,会出现死锁,锁定粒度最小,发生锁冲突的概率最低,并发度最高
29 从所得类别上分,mysql有哪些锁
- 从所得类别上来讲,有共享锁和排他锁
- 共享锁:又叫做读锁,当用户需要进行数据读取时,读数据加上共享锁。共享锁可以同时加上多个
- 排他锁:又叫做写锁。当用户需要进行数据写入时,对数据加上排他锁。排他锁只可以加一个,他和其他的排他锁以及共享锁都相斥
30 innodb中的行锁怎么实现的
- innodb时基于索引来完成行锁
31 innodb存储引擎的所算法有三种
- Record Lock:单个行记录上的锁
- Gap Lock:间隙锁,锁定一个范围,不包括记录本身
- Next-Key Lock:record + gap锁定一个范围,包含记录本身
- 相关知识点:
1. innodb对于行的查询使用next-key lock
2. next-locking keying为了解决幻读问题
3. 当查询的索引包含有唯一属性时,next-key lock降级为record key
4. gap锁设计的目的时为了阻止多个事务将记录插入到同一范围内,二者会导致欢度问题
5. 有两种方式显示关闭gap锁:出了外键约束和唯一性检查外,其余情况使用record lock
A:将事务隔离级别设置为读已提交
B:将参数innodb_locks_unsafe_for_binlog设置为1
32 什么时死锁,怎么解决
- 死锁是指两个或多个事务在统一资源上相互占用,并请求锁定对方的资源,从而导致恶行循环的现象
- 常见解决死锁方法:
1. 如果不同程序会并发存取多个表,尽量约定以相同的顺序访问表,可以大大降低死锁机会
2. 在同一个事务中,尽可能做到一次锁定所需要的所有资源,可以减少死锁产生的概率
3. 对于非常容易产生死锁的业务部分,可以尝试使用升级锁定粒度,通过表级锁减少死锁产生概率
4. 如果业务处理不好可以使用分布式事务锁或者使用乐观锁
33 数据库乐观锁和悲观锁是什么,怎么实现的
- 数据库管理系统中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性。乐观并发控制和悲观并发控制时并发控制主要采用的技术手段
- 悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。在查询完数据的时候就把事务锁起来,知道提交事务。实现方式:数据库中的锁机制
- 乐观锁:假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。在修改数据的时候把事务锁起来,通过版本的方式来进行锁定。实现方式:乐观锁一般会采用版本号机制或者CAS算法实现
- 两种所使用场景:从上面对两种锁的介绍,两种所各有优点。乐观锁适用于写比较少的情况(多读场景),即冲突真的很少发生的时候,这样可以省去锁的开销,加大整个系统吞吐量。但是如果是多写的情况,一般会经常发生冲突,这就会导致上层应用不断进行重试,这样反倒降低了性能。所以多写的场景下使用悲观锁就比较合适
34 视图
- 为了提高复杂SQL语句的复用性和表操作的安全性,mysql数据库管理系统提供了视图特性。所谓视图,本质上是一种虚拟表,在物理上不存在,其内容与真实表类似,包含有一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值形式存在。行和列数据来自定义视图的查询所引用基本表,并且在具体引用视图时动态产生
- 视图使开发者只关心感兴趣的某些特定顶数据和所负责的特定任务,只能看到视图中所定义的数据,而不是视图所引用表中的数据,从而提高了数据空中数据的完整性
35 视图有哪些特点
- 视图特点如下:
1. 视图的列可以来自不同的表,是表的抽象和在逻辑意义上建立的新关系
2. 视图是由基本表(实表)产生的表(虚表)
3. 视图的建立和删除不影响基本表
4. 对视图内容的更新(增删改)直接影响基本表
5. 当视图来自多个基本表时,不允许添加和删除数据
- 视图擦欧总包括创建视图,查看视图,删除视图和修改视图
36 视图使用场景由哪些
- 视图根本用途:简化SQL查询,提高开发效率。如果说还有另一个用途俺就是兼容老的表结构
- 视图常见使用场景:
- 重用SQL语句
- 简化复杂的SQL操作。在编写查询后,可以方便的重用它而不必知道他的基本查询细节
- 使用表的组成部分而不是整张表
- 保护数据。可以给用户授予表的特定部分的访问权限而不是整个表的访问权限
- 更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据
37 视图优点
- 查询简单化。视图能简化用户的操作
- 数据安全性。视图使用户能够以多种角度看待同一数据,能够对机密数据提供安全保护
- 逻辑数据独立性。视图对重构数据库提供了一定程度上的逻辑独立性
38 视图缺点
- 性能:数据库必须把视图的查询转换为对基本表的查询,如果这个视图是由一个复杂的多表查询所定义,那么即使是视图的一个简单查询,数据库也把它编程一个复杂的结合体,需要花费一定的时间
- 修改限制:当用户视图修改视图的某些行是,数据库必须把它转化为对基本表某些行的修改。事实上,当从视图中插入或删除数据时,情况也是这个样子。对于简单来说,这是很方便的,但是对于比较复杂的视图,可能时不可修改的
39 什么是游标
- 游标是系统为用户开设的一个数据缓冲区,存访SQL语句的执行结果,每个游标区有一个民资。可以通过游标逐一获取记录并赋值给主变量,交由诸语言进一步处理
40 什么是存储过程,有什么优缺点
- 存储过程是一个预编译的SQL语句,优点是允许模块化设计,就是说只需要创建一次,以后再该程序中就可以调用多次。如果某次操作需要执行多次SQL,使用存储过程比单纯SQL语句执行要快
- 优点:
1. 存储过程是预编译过的,执行效率较高
2. 存储过程的代码直接存放在数据库中,通过存储过程名直接调用,减少网络通讯
3. 安全性高,执行存储过程需要一定权限的用户
4. 存储过程可以重复使用,减少数据库开发人员的工作量
- 缺点:
1. 调试麻烦
2. 一直问题,数据库端代码当然是与数据库相关的。
3. 重新编译问题,因为后端代码是运行前编译的,如果带有引用关系的对象发生改变时,受影响的存储过程,包将需要重新编译
4. 如果一个程序系统中大量使用存储过程,到程序交付使用的时候随着用户需求的增加会导致数据结构的变化,接着就是系统相关的问题了,最后如果用户向维护改系统可以说是很难很难,而且代价是空前的,维护起来更麻烦
41 什么是触发器,触发器使用场景有哪些
- 触发器是用户定义在关系表上的一类有时间驱动的特殊存储过程。触发器是指一段代码,当触发某个事件时,自动执行这些代码:
- 使用场景:
1. 可以通过数据库中的相关表实现级联更改
2. 实时监控某张表中某个字段的更改而实现相应处理
3. 生成某些业务编号
4. 不要滥用,会造成数据库以及应用程序维护困难
42 mysql中有哪些触发器
- before insert
- after insert
- before update
- after update
- before delete
- after delete
43 常用SQL语句分为哪几类
- DDL
- DML
- DQL
- DCL
44 超键,候选键,主键,外键分别是什么
45 SQL约束有哪几种
- not null
- unique
- primary
- foreign key
- check
46 六种关联查询
- 交叉连接
- 内连接
- 等值连接
- 不等值连接
- 自连接
- 外连接
- 左外连接
- 右外连接
- 联合查询
- 全连接
47 什么是子查询
48 子查询三种情况
- 子查询是当行单列
- 子查询是多行单列
- 子查询是多行多列
49 mysql中的in和exist区别
- mysql中的in是把外表和内表做hash连接,而exist语句是对外表做循环,每次循环再对内表进行查询
- 如果内外表大小相当,则in和exist差别不大
- 如果内表大外表小,则exist效率更高
- 如果内表小外表大,则in效率更高
50 char和varchar区别
51 drop,delete,truncate区别
- 类型
- delete:DML
- truncate:DDL
- drop:DDL
- 回滚
- delete:可回滚
- truncate:不可回滚
- drop:不可回滚
- 删除内容
- delete:表结构还在,删除部分或全部数据
- truncate:表结构还在,删除全部数据
- drop:从数据库中删除表,所有数据行,索引和权限
- 删除速度
- delete:逐行删除,慢
- truncate:快
- drop:最快
52 union与union all区别
- 如果使用union all,不会合并重复的记录行
- 效率union高于union all
53 explain执行计划
54 sql生命周期
55 大表数据查询怎么优化
- 优化库表,SQL语句加索引
- 加缓存,redis
- 主从复制,读写分离
- 垂直拆分
- 水平切分
56 超大分页怎么处理
57 mysql分页
58 慢查询日志
59 查询优化从哪些方面入手
- 查询条件没有命中索引
- 加载了不需要的数据
- 数据量太大
60 如何优化
- 首先看是否加载了不需要的数据
- 然后分析执行计划,获取索引使用情况,修改语句或者修改索引,使语句尽可能的命中索引
- 如果对语句的优化已经无法进行,考虑是否使数据量太大,如果是的话考虑横向或者纵向分表
61 字段为什么要求定义为not null
- null值会占用更多的字节,且会在程序中造成很多与预期不符的情况
62 优化查询过程中的数据访问
- 访问数据太多导致查询性能下降
- 确定应用程序是否在检索大量超过需要的数据,可能是太多行或列
- 确认Mysql服务器是否在分析大量不必要的行
- 避免犯如下sql错误
- 查询不需要的数据,使用limit解决
- 多表关联返回全部列,指定返回全部列解决
- 总是返回全部列,避免使用select * 解决
- 重复查询相同的数据,使用缓存解决
- 是否扫描额外记录,使用explain查看执行计划
- 如果发现查询需要扫描大量的数据,只返回少量的行,可以通过如下做优化
- 使用索引覆盖扫描
- 改变库表结构,修改表范式
- 重写SQL
63 优化长难查询语句
- 一个复杂查询还是多个简单查询
- mysql内部每秒能扫描上百万行数据,相比之下,响应数据返回给客户端就慢很多
- 使用尽可能小的查询是好的,但是有时将一个大的查询拆分成多个小的查询是有必要的
- 切分查询
- 将一个大的查询分为多个小的相同查询
- 执行单个查询减少锁竞争
- 在引用曾关联更容易对数据库进行拆分
- 减少冗余记录查询
64 优化特定类型的查询语句
65 优化关联查询
- 确定on或者using子句中是否有索引
- 排序时索引问题
66 优化子查询
- 使用关联查询代替
- 优化Group BY 和 Distinct
67 union与union all
68 哪些情况导致索引失效
69 为什么要优化
- 系统的吞吐量瓶颈往往出现在数据库的访问速度上
- 随着应用程序的运行,数据库中的数据会越来越多,处理时间会相应变慢
- 数据是存放在磁盘上,读写速度无法和内存相比
- 优化原则:减少系统瓶颈,减少资源占用,增加系统反应速度
70 数据库结构优化
- 将字段很多的表分解成多个表
- 增加中间表
- 增加冗余字段
71 数据库cpu飙升到500%怎么办
- 先通过top命令观察是否是mysqld占用导致
- 如果是,show processlist看看里面跑的session的情况,是不是又消耗资源的sql在进行
- 找出高消耗sql,查看执行计划是否正确
- kill掉这些线程,同时观察cpu使用率是否下降,然后调整后再跑SQL
72 达标如何优化
73 分库分表
74 分库分表引发的问题
75 mysql复制原理及流程
76 读写分离又哪些解决方案
77 备份计划实现原理
78 数据表损坏的修复方式有哪些
79 mysql最大数据量
80 mysql最大并发数
81 建议将单词查询耗时控制在0.5秒以内
82 mysql实施原则
- 充分利用但不滥用索引,索引也消耗磁盘和CPU
- 不推荐使用数据库函数格式话数据,交给应用程序处理
- 不推荐使用外键约束,用应用程序保证数据准确性
- 写多读少的场景,不推荐使用唯一索引,用应用程序保证唯一性
- 适当冗余字段,尝试创建中间表,用应用程序计算中间结果,用空间换时间
- 不允许执行极度耗时的事务,配合应用程序拆分成更小的事务
- 预估重要数据集的负载和数据增长态势,提前优化
83 数据类型选择原则,更简单或者占用空间更小
- 如果长度能够满足,整型尽量使用tinyint,smallint,mediumint而非int
- 如果字符串长度确定,采用char
- 如果varchar能够满足,不采用text
- 尽量采用timestamp而非datetime
84 避免空值
- mysql中字段为null时依然占用空间,会使索引,索引统计更加复杂。从null更新到非null并不能做到原地跟新,容易发生索引分裂影响性能。尽可能将null值用有意义的值代替
85 索引优化
- 分页查询很重要,如果查询数量超过30%,mysql不会使用索引
- 单表索引数不要超过5个,单个字段索引数不要超过5个
- 字符串可使用前缀索引,前缀长度控制在5-8个字符
- 字段唯一性太低,增加索引没有意义,如是否删除及性别
86 SQL优化
- 分批处理
- 不等于优化
- OR优化
- in优化
- like优化
- join优化
- limit优化