mysql-问答
为什么B+Tree比B-Tree更适合数据库的索引结构?
B+Tree是B-Tree的一个变种,相较于B-Tree来说,B+Tree有两个特点:1.叶子节点包含了所有的关键字信息,且有横向链表连接;2.所有非叶子节点仅包含其子树根节点中最大或最小关键字。相较于B-Tree,B+Tree有三个优势:1.IO次数更少;2.查询性能稳定;3.范围查询简单。为什么单调递增字段(AUTO_INCREMENT)比非单调字段作为InnoDB的主键更好?
InnoDB在磁盘上的数据是按照主键排序存储的(单个数据块内)。为什么可选择性高的字段创建索引效率更高?
选择性高的字段具有更高的筛选性。InnoDB和MyISAM的索引结构有什么异同?
InnoDB的主键和辅助索引的关系是什么?
InnoDB的主键索引:索引即数据,索引的叶子结点不仅包含索引字段,而且还包含其他所有字段,数据是以主键顺序在磁盘上存储的(单个数据块内)。
InnoDB的辅助索引:辅助索引除了存储索引字段外,还存储了主键值,以辅助索引检索数据,必须根据辅助索引查找到主键值,再去主键索引里面查找数据。也就是说如果你通过辅助索引查找数据,要先在B+树中查找到主键,然后根据主索引查找到对应的记录,查找两次。InnoDB中为什么不建议过长的字段作为主键?
因为辅助索引中叶子节点存储主键值,太长会导致辅助索引的额外存储空间太大。索引都有哪些类型?常用的有哪些?
- B+Tree、Hash、全文;
- 主键、唯一索引、非唯一索引;
- 单列索引、组合索引;
什么是索引的最左前缀和可选择性?
最左前缀:从索引的最左边开始组合;
可选择性:不重复的索引值(基数)和表总行数的比值。为什么查询要遵守索引的最左前缀原则?
索引扫描需要先在叶子节点中确定一个起点和终点。为什么范围查询字段最好放到组合索引的最后?
组合索引中,范围查询字段后的索引会失效。什么是覆盖索引?
索引数据包含了需要查找的、筛选的所有字段,只扫描索引不回表!数据库索引为什么要使用树结构存储呢?
树的查询效率高,而且可以保持有序。什么是小表,什么是大表?什么是驱动表?什么是被驱动表?
解决like ‘%字符串%’时索引不被使用的方法??
使用覆盖索引。索引为什么没有使用二叉树查找树来实现?
从算法逻辑上来讲,二叉查找树的查找速度和比较次数都是最小的。但是我们不得不考虑一个问题,磁盘IO。数据库的索引是存储在磁盘上的,当数据量比较大的时候,索引的大小可能有几个G甚至更多。当我们利用索引查询的时候,不可能把所有索引全部加载到内存中,能做的只有逐一加载每一个磁盘页,这里的磁盘页对应着索引树的节点。exist和in的区别和使用
1 | select * from a where id in (select id from b); |
当b表数据小于a表时,用in优于exists。
1 | select * from a where exists (select 1 from b where b.id = a.id); |
当a表的数据小于b表的数据时,用exists。
Innodb和MyISAM有什么区别?
Innodb支持事务,MyISAM不支持
Innodb支持外键,MyISAM不支持
Innodb是行锁,MyISAM是表锁
Innodb不支持全文索引,MyISAM支持全文索引
Innodb不保存表的具体行数,MyISAM用一个变量保存了整个表的行数
当查询命中索引的时候,还通过API调用存储引擎吗?
当查询使用了覆盖索引,还通过API调用存储引擎吗?
对于一个查询
select * from table_a where name ='tom' ;
,没有命中索引,where条件是在存储引擎还是服务器层(存储引擎返回了所有的行)进行过滤的?如果命中索引,结果又如何? 对于 group by ,order by,limit 呢?命中索引和没有命中的情况,在存储引擎层执行还是在服务器层执行?limit是在什么时候执行的?存储引擎层还是服务器层?如果是在存储引擎层,那么where和order by、group by 是不是也得先在存储引擎执行?如果是在服务器层,那么是不是意味着存储引擎返回了所有的行,然后在服务器层进行where,order by和group by,然后limit,再返回给客户端
另外,所说的回表查询,是不是指在存储引擎层完成的还是说所中索引返回服务器层,然后服务器层又向存储引擎层请求了一次数据?
当命中索引的时候,存储引擎会使用到索引下推,则返回给服务器层所有符合where条件行,服务器层判断如果是覆盖索引且能满足order by group by排序,则不进行文件排序和创建临时表,如果不是覆盖索引,则回表查询,然后进行order by, group by排序,此时会进行文件排序或创建临时表。
当没有命中索引的时候,存储引擎会查询所有记录,然后返回给服务器层使用where进行过滤,进一步进行order by ,group by ,此时会进行内存排序或文件排序或创建临时表。
最终使用limit丢弃数据返回给客户端。