mysql相关

对着背影说爱祢 提交于 2020-01-09 12:18:22

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

前言:在2019年的年末,我又再一次的踏上了面试的漫漫征途。每次的面试准备都是对自己学习的一次积累。目前已经尘埃落定,将自己面试准备的东西做一次整理。
面试准备时长:1.5个月
mysql基本上每次面试都会问道,对于工作四年的开发人员来说,需要准备的知识也非常多。
一、事务隔离级别
  1. read uncommied:即便事务没有commit,但是我们仍然能够读到未提交的数据,这是所有隔离级别中最低的一种
  2. read commited:可以读取其他事务提交的数据,这也是大多数数据库默认的隔离级别
  3. repeatable read:可重读 --mysql的默认隔离级别
  4. serializable:串行化,将当前会话的隔离级别设置为serilizable时,其他会话对该表的写操作将会被挂起。这样做对性能会造成影响。
二、索引

索引的本质

官方定义为:索引(index)是帮助mysql高效获取数据的数据结构。

B-Tree和B+Tree

b-tree的示意图如下所示:

btree索引的每个节点中不仅包含数据的key值,还有data值。而每一页的存储空间是有限的,如果data数据较大时,会导致每个节点(即一个页)能存储的key的数量很小,当存储的数据量很大时,同样会导致B-tree的深度较大,增大查询时的磁盘I/O次数,进而影响查询效率。

b+tree的示意图如下

b+tree中,

  • 非叶子节点只存储键值信息
  • 所有叶子节点之间都有一个链指针
  • 数据记录都存放在叶子节点上

使用b+tree做索引而不使用b-tree或者红黑树做索引的原因

  • B+tree只有叶节点存放数据,其余节点用来索引,而b-tree数每个索引节点都有data域,节点小,磁盘io次数就少
  • B+tree所有data域在叶子节点,并且所有叶子节点之间都有指针。这样遍历叶子节点就会获得全部的数据
  • 在大规模数据存储的时候,红黑树由于树的深度过大而造成磁盘io读写过于频繁,进而导致效率低下

聚簇索引和非聚簇索引

在b+tree中,根据叶子节点的内容,索引分为主键索引和非主键索引

  1. 主键索引(聚簇索引):的叶子节点存的数据是整行数据。表数据按照索引的顺序来存储的,也就是说索引的顺序与表中记录的物理顺序一致。在一张表上只能创建一个聚簇索引,因为真实数据的物理顺序只能是一种
  2. 非主键索引(辅助索引)叶子结点存储的是整行数据的主键,键值是索引。表数据存储顺序与索引顺序无关。
二级索引的叶节点存储的是主键值,而不是行指针,这是为了减少当出现行移动或者数据页分裂时二级索引的维护工作,但会让二级索引占用更多的空间。

辅助索引查询数据时,需要经过两步:

  1. InnoDB存储引擎会遍历辅助索引找到主键
  2. 通过主键在聚集索引中查找完整的行记录数据

mysql建表时考虑的情况

  1. 选择最适用的字段属性,将字段的宽度设计的尽可能小
  2. 尽可能把字段设置为not null,这样在执行查询的时候,数据库就不用去比较null值

mysql查看某个表的索引情况

show index from t_table_name

索引失效的集中情况

  1. 如果条件中有or,即使其中有条件带索引也无效(想要用or,又想让索引生效,只能将or条件中的每个列都加上索引)
  2. 对于组合索引,不使用索引的第一部分,则不会使用索引。(组合索引的第一个字段必须包含在查询条件中,最左前缀,就是最左匹配原则。比如建立一个ABC多列索引,则相当于创建了A单列索引,AB组合索引,以及ABC组合索引)
  3. like以%开头
  4. 如果列类型是字符串,那一定要在条件中将数据使用引号,否则不使用索引

建索引的情况

  1. 主键自动建立唯一索引
  2. 频繁作为查询条件的字段应该建立索引
  3. 查询中与其他表关联的字段,外键关系建立索引
  4. 组合索引性价比更高
三、explain的用法,sql优化
EXPLAIN select * from t_fund_pay_record where `STATUS`='3';

  1. table:显示这一行的数据是关于哪张表的

  2. type:显示使用了何种类型,从最好到最差的连接类型为const,eq_reg,ref,range,index,all

    • system:表仅有一行(=系统表)。这是const联接类型的一个特例。
    • const:表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!
    • eq_ref:对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。
    • ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。
    • ref_or_null:该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。
    • index_merge:该联接类型表示使用了索引合并优化方法。
    • unique_subquery:该类型替换了下面形式的IN子查询的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr) unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。
    • index_subquery:该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
    • range:只检索给定范围的行,使用一个索引来选择行。
    • index:该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。
    • ALL:对于每个来自于先前的表的行组合,进行完整的表扫描。
  3. possible_keys:指出MySQL能使用哪个索引在该表中找到行

  4. key:显示mysql实际决定使用的键(索引)。如果没有选择索引,键是null

  5. key_len:显示mysql决定使用的键长度。如果键是null,则长度为null

  6. ref:显示使用哪个列或者常数与key一起从表中选择行

  7. rows:显示mysql认为它执行查询时必须检查的行数。多行之间的数据相乘可以估算要处理的行数

  8. filtered:显示了通过条件过滤出的行数的百分比的估计值

  9. extra:包含mysql解决查询的详细信息

    • Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
    • Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。
    • range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。
    • Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行。
    • Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。
    • Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。
    • Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。
    • Using sort_union(...), Using union(...), Using intersect(...):这些函数说明如何为index_merge联接类型合并索引扫描。
    • Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。

参考:

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!