1.为什么用自增列作为主键
- 如果我们定义了主键(PRIMARY KEY),那么 InnoDB 会选择主键作为聚集索引、如果没有显式定义主键,则 InnoDB 会选择第一个不包含有 NULL值的唯一索引作为主键索引、如果也没有这样的唯一索引,则 InnoDB 会选择内置 6 字节长的 ROWID 作为隐含的聚集索引(ROWID 随着行记录的写入而主键递增,这个 ROWID 不像 ORACLE 的 ROWID 那样可引用,是隐含的)。
- 数据记录本身被存于主索引(一颗 B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL 会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB 默认为 15/16),则开辟一个新的页(节点)。
- 如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页
- 如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL 不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE 来重建表并优化填充页面。
2.为什么使用数据索引能提高效率
- 数据索引的存储是有序的
- 在有序的情况下,通过索引查询一个数据是无需遍历索引记录的
- 极端情况下,数据索引的查询效率为二分法查询效率,趋近于 log2(N)
3.B+树索引和哈希索引的区别
B+树是一个平衡的多叉树,从根节点到每个叶子节点的高度差值不超过 1,而且同层级的节点间有指针相互链接,是有序的
哈希索引就是采用一定的哈希算法,把键值换算成新的哈希值,检索时不需要类似 B+树那样从根节点到叶子节点逐级查找,只需一次哈希算法即可,是无序的
4.哈希索引的优势
等值查询。哈希索引具有绝对优势(前提是:没有大量重复键值,如果大量重复键值时,哈希索引的效率很低,因为存在所谓的哈希碰撞问题。)
5.哈希索引不适用的场景
- 不支持范围查询
- 不支持索引完成排序
- 不支持联合索引的最左前缀匹配规则
6.B 树和 B+树的区别
- B 树,每个节点都存储 key 和 data,所有节点组成这棵树,并且叶子节点指针为 nul,叶子结点不包含任何关键字信息。
- B+树,所有的叶子结点中包含了全部关键字的信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接,所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。(而 B 树的非终节点也包含需要查找的有效信息)
7.为什么说 B+比 B 树更适合实际应用中操作系统的文件索引和数据库索引?
- B+的磁盘读写代价更低 B+的内部结点并没有指向关键字具体信息的指针。因此其内部结点相对 B 树更小。如果把所有同一内部结点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多。一次性读入内存中的需要查找的关键字也就越多。相对来说 IO 读写次数也就降低了
- B±tree 的查询效率更加稳定由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。
8.MySQL 联合索引
- 联合索引是两个或更多个列上的索引。对于联合索引:Mysql 从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如索引是 key index (a,b,c). 可以支持 a 、 a,b 、 a,b,c 3 种组合进行查找,但不支持 b,c 进行查找 .当最左侧字段是常量引用时,索引就十分有效。
- 利用索引中的附加列,您可以缩小搜索的范围,但使用一个具有两列的索引 不同于使用两个单独的索引。复合索引的结构与电话簿类似,人名由姓和名构成,电话簿首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。如果您知 道姓,电话簿将非常有用;如果您知道姓和名,电话簿则更为有用,但如果您只知道名不姓,电话簿将没有用处。
9.什么情况下应不建或少建索引
- 表记录太少
- 经常插入、删除、修改的表
- 数据重复且分布平均的表字段,假如一个表有 10 万行记录,有一个字段A 只有 T 和 F 两种值,且每个值的分布概率大约为 50%,那么对这种表 A 字段建索引一般不会提高数据库的查询速度。
- 经常和主字段一块查询但主字段索引值比较多的表字段
10.什么是表分区?
表分区,是指根据一定规则,将数据库中的一张表分解成多个更小的,容易管理的部分。从逻辑上看,只有一张表,但是底层却是由多个物理分区组成。
11.表分区与分表的区别
分表:指的是通过一定规则,将一张表分解成多张不同的表。比如将用户订单记录根据时间成多个表。 分表与分区的区别在于:分区从逻辑上来讲只有一张表,而分表则是将一张表分解成多张表。
12.表分区有什么好处?
- 分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备。
- 和单个磁盘或者文件系统相比,可以存储更多数据。
- 优化查询。在 where 语句中包含分区条件时,可以只扫描一个或多个分区表来提高查询效率;涉及 sum 和 count 语句时,也可以在多个分区上并行处理,最后汇总结果。
- 分区表更容易维护。例如:想批量删除大量数据可以清除整个分区。
- 可以使用分区表来避免某些特殊的瓶颈,例如 InnoDB 的单个索引的互斥访问,ext3 问价你系统的 inode 锁竞争等。
13.分区表的限制因素
- 一个表最多只能有 1024 个分区。
- MySQL5.1 中,分区表达式必须是整数,或者返回整数的表达式。在MySQL5.5 中提供了非整数表达式分区的支持。
- 如果分区字段中有主键或者唯一索引的列,那么多有主键列和唯一索引列都必须包含进来。
- 分区表中无法使用外键约束
- MySQL 的分区适用于一个表的所有数据和索引,不能只对表数据分区而不对索引分区,也不能只对索引分区而不对表分区,也不能只对表的一部分数据分区。
14.如何判断当前 MySQL 是否支持分区?
使用命令
show variables like '%partition%'
值为 YES,表示支持分区。
15.MySQL 支持的分区类型有哪些?
- RANGE 分区:这种模式允许将数据划分不同范围。
- LIST 分区:这种模式允许系统通过预定义的列表的值来对数据进行分割。
- HASH 分区 :这中模式允许通过对表的一个或多个列的 Hash Key 进行计算,最后通过这个 Hash 码不同数值对应的数据区域进行分区。
- KEY 分区 :上面 Hash 模式的一种延伸,这里的 Hash Key 是 MySQL系统产生的。
16.四种隔离级别
- Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
- Read committed (读已提交):可避免脏读的发生。
- Read uncommitted (读未提交):最低级别,任何情况都无法保证。
- Repeatable read (可重复读):可避免脏读、不可重复读的发生。
17.行级锁定的优点
- 当在许多线程中访问不同的行时只存在少量锁定冲突。
- 回滚时只有少量的更改。
- 可以长时间锁定单一的行。
18.行级锁定的缺点
- 比页级或表级锁定占用更多的内存。
- 当在表的大部分中使用时,比页级或表级锁定速度慢,因为你必须获取更多的锁。
- 如果你在大部分数据上经常进行 GROUP BY 操作或者必须经常扫描整个表,比其它锁定明显慢很多。
- 用高级别锁定,通过支持不同的类型锁定,你也可以很容易地调节应用程序,因为其锁成本小于行级锁定。
19.MySQL 优化
- 开启查询缓存,优化查询。
- explain 你的 select 查询,这可以帮你分析你的查询语句或是表结构的性能瓶颈。
- 当只要一行数据时使用 limit 1,MySQL 数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据。
- 为搜索字段建索引。
- 使用 ENUM 而不是 VARCHAR,如果你有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是 VARCHAR。
- 垂直分表。
- 选择正确的存储引擎。
20.key 和 index 的区别
key 是数据库的物理结构,它包含两层意义和作用,一是约束(偏重于约束和规范数据库的结构完整性),二是索引(辅助查询用的)。包括primary key, unique key, foreign key 等
index 是数据库的物理结构,它只是辅助查询的,它创建时会在另外的表空间(mysql 中的 innodb 表空间)以一个类似目录的结构存储。索引要分类的话,分为前缀索引、全文本索引等
21.Mysql 中 MyISAM 和 InnoDB 的区别有哪些
区别: 1、InnoDB 支持事务,MyISAM 不支持,对于 InnoDB 每一条 SQL 语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条 SQL 语言放在 begin 和 commit 之间,组成一个事务。 2、InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败。 3、InnoDB 是聚集索引,数据文件是和索引绑在一起的,必须要有主键,通过主键索引效率很高。 4、InnoDB 不保存表的具体行数,执行 select count(*) from table 时需要全表扫描。 5、Innodb 不支持全文索引,而 MyISAM 支持全文索引,查询效率上MyISAM 要高;
|