mysql-问答

  1. 为什么B+Tree比B-Tree更适合数据库的索引结构?
    B+Tree是B-Tree的一个变种,相较于B-Tree来说,B+Tree有两个特点:1.叶子节点包含了所有的关键字信息,且有横向链表连接;2.所有非叶子节点仅包含其子树根节点中最大或最小关键字。相较于B-Tree,B+Tree有三个优势:1.IO次数更少;2.查询性能稳定;3.范围查询简单。

  2. 为什么单调递增字段(AUTO_INCREMENT)比非单调字段作为InnoDB的主键更好?
    InnoDB在磁盘上的数据是按照主键排序存储的(单个数据块内)。

  3. 为什么可选择性高的字段创建索引效率更高?
    选择性高的字段具有更高的筛选性。

  4. InnoDB和MyISAM的索引结构有什么异同?

  1. InnoDB的主键和辅助索引的关系是什么?
    InnoDB的主键索引:索引即数据,索引的叶子结点不仅包含索引字段,而且还包含其他所有字段,数据是以主键顺序在磁盘上存储的(单个数据块内)。
    InnoDB的辅助索引:辅助索引除了存储索引字段外,还存储了主键值,以辅助索引检索数据,必须根据辅助索引查找到主键值,再去主键索引里面查找数据。也就是说如果你通过辅助索引查找数据,要先在B+树中查找到主键,然后根据主索引查找到对应的记录,查找两次。

  2. InnoDB中为什么不建议过长的字段作为主键?
    因为辅助索引中叶子节点存储主键值,太长会导致辅助索引的额外存储空间太大。

  3. 索引都有哪些类型?常用的有哪些?

    • B+Tree、Hash、全文;
    • 主键、唯一索引、非唯一索引;
    • 单列索引、组合索引;
  4. 什么是索引的最左前缀和可选择性?
    最左前缀:从索引的最左边开始组合;
    可选择性:不重复的索引值(基数)和表总行数的比值。

  5. 为什么查询要遵守索引的最左前缀原则?
    索引扫描需要先在叶子节点中确定一个起点和终点。

  6. 为什么范围查询字段最好放到组合索引的最后?
    组合索引中,范围查询字段后的索引会失效。

  7. 什么是覆盖索引?
    索引数据包含了需要查找的、筛选的所有字段,只扫描索引不回表!

  8. 数据库索引为什么要使用树结构存储呢?
    树的查询效率高,而且可以保持有序。

  9. 什么是小表,什么是大表?什么是驱动表?什么是被驱动表?

  10. 解决like ‘%字符串%’时索引不被使用的方法??
    使用覆盖索引。

  11. 索引为什么没有使用二叉树查找树来实现?
    从算法逻辑上来讲,二叉查找树的查找速度和比较次数都是最小的。但是我们不得不考虑一个问题,磁盘IO。数据库的索引是存储在磁盘上的,当数据量比较大的时候,索引的大小可能有几个G甚至更多。当我们利用索引查询的时候,不可能把所有索引全部加载到内存中,能做的只有逐一加载每一个磁盘页,这里的磁盘页对应着索引树的节点。

  12. 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。

  1. Innodb和MyISAM有什么区别?

    • Innodb支持事务,MyISAM不支持

    • Innodb支持外键,MyISAM不支持

    • Innodb是行锁,MyISAM是表锁

    • Innodb不支持全文索引,MyISAM支持全文索引

    • Innodb不保存表的具体行数,MyISAM用一个变量保存了整个表的行数

  2. 当查询命中索引的时候,还通过API调用存储引擎吗?

  3. 当查询使用了覆盖索引,还通过API调用存储引擎吗?

  4. 对于一个查询 select * from table_a where name ='tom' ;,没有命中索引,where条件是在存储引擎还是服务器层(存储引擎返回了所有的行)进行过滤的?如果命中索引,结果又如何? 对于 group by ,order by,limit 呢?命中索引和没有命中的情况,在存储引擎层执行还是在服务器层执行?

  5. limit是在什么时候执行的?存储引擎层还是服务器层?如果是在存储引擎层,那么where和order by、group by 是不是也得先在存储引擎执行?如果是在服务器层,那么是不是意味着存储引擎返回了所有的行,然后在服务器层进行where,order by和group by,然后limit,再返回给客户端

  6. 另外,所说的回表查询,是不是指在存储引擎层完成的还是说所中索引返回服务器层,然后服务器层又向存储引擎层请求了一次数据?

  7. 当命中索引的时候,存储引擎会使用到索引下推,则返回给服务器层所有符合where条件行,服务器层判断如果是覆盖索引且能满足order by group by排序,则不进行文件排序和创建临时表,如果不是覆盖索引,则回表查询,然后进行order by, group by排序,此时会进行文件排序或创建临时表。

    当没有命中索引的时候,存储引擎会查询所有记录,然后返回给服务器层使用where进行过滤,进一步进行order by ,group by ,此时会进行内存排序或文件排序或创建临时表。

    最终使用limit丢弃数据返回给客户端。

0%