索引有哪些作用呢

简介: 基础

覆盖索引是什么?

就是假如有一个联合索引(a,b,c),如果我们只是需要a,b,c这几个字段的数据,查询时就不需要根据主键id去聚集索引里面回表查询了。

SELECT a,b,c FROM user where a = 1点击复制代码复制出错复制成功

哪些情况需要建索引:

  1. 主键,唯一索引
  2. 经常用作查询条件的字段需要创建索引
  3. 经常需要排序、分组和统计的字段需要建立索引
  4. 查询中与其他表关联的字段,外键关系建立索引

哪些情况不要建索引?

  1. 表的记录太少,百万级以下的数据不需要创建索引
  2. 经常增删改的表不需要创建索引
  3. 数据重复且分布平均的字段不需要创建索引,如 true,false 之类。
  4. 频发更新的字段不适合创建索引
  5. where条件里用不到的字段不需要创建索引

主键,唯一性索引,普通索引的区别是什么?

一个表中可以有多个唯一性索引,但只能有一个主键。

1.在查询时,如果是使用的是主键,或者是唯一性索引查询,查到后就返回了,普通索引还会继续向后遍历,直到第一个不满足条件的才会返回,普通索引会多检索几次。几乎没有什么影响。

2.更新时普通索引需要判断唯一性。

3.主键是聚集索引,普通所以是非聚集索引。

InnoDB和MyISAM的区别是什么?

InnoDB

是 MySQL 默认的事务型存储引擎,只有在需要它不支持的特性时,才考虑使用其它存储引擎。

实现了四个标准的隔离级别,默认级别是可重复读(REPEATABLE READ)。在可重复读隔离级别下,通过多版本并发控制(MVCC)+ Next-Key Locking 防止幻影读。

主索引是聚集索引,在索引中保存了数据,从而避免直接读取磁盘,因此对查询性能有很大的提升。其次是聚集索引每个叶子节点按照主键id从小到大顺序存储了大量数据行,而每个叶子节点在实现上是一个内存页,磁盘IO读取时是读取一个内存页,会进行一定的预读,所以在进行范围查找时,InnoDB引擎效率更高,而MyISAM则需要对查找范围内所有数据行进行随机读取。(每条数据都是存储在不同地址上)

内部做了很多优化,包括从磁盘读取数据时采用的可预测性读、能够加快读操作并且自动创建的自适应哈希索引、能够加速插入操作的插入缓冲区等。

支持真正的在线热备份。其它存储引擎不支持在线热备份,要获取一致性视图需要停止对所有表的写入,而在读写混合场景中,停止写入可能也意味着停止读取。

MyISAM

不支持事务,不支持行级锁,只能全表加锁,读取时会对所有表加共享锁,写入时会对表加排他锁。

什么是分库分表?

一般认为单表数据量在1000万时,查询效率是最合适的,如果超过1000万,执行性能就会下降,可以考虑分库分表。

垂直切分

就是根据列进行分表,例如根据业务,来对表进行拆分成不同的表,或者根据使用频率,将常用的列分在一个表里面,将不常用的列分在一个表里面。

水平切分

将表根据行来进行分表,将一个表拆分成多个表结构相同的表。

第一种 一般是用主键ID对数据表的数量进行取模运算,得到的余数就是新表的位置。(如果是字段是字符串,那么就根据字符串计算出哈希值,然后除以表的数量,得到新库的位置)

第二种 根据时间来拆分,主表只存储最近两个月的数据,副表存储之前的数据。这种主要是适合哪种访问的数据跟时间相关性比较大的情况,例如统计,我有看某新闻网站他们的技介绍,他们的文章会有一个PV,UV统计表,就是每天大概有200万的文章有PV,UV,也就是数据库每天会新增200万行的数据,一般来说查文章近期的UV,PV会多一些,查昨日PV,一周PV,或者一个月的PV会多一些。所以是安装时间来划分热库和冷库,一月一个表,或者一天一表。

问题

1.事务问题,如果在事务里面操作一个表,然后再操作另外一个表,效率会比较低,然后也比较麻烦。

2.跨库join的问题

在拆分之前,系统中很多列表和详情页所需的数据是可以通过sql join来完成的。而拆分后,数据库可能是分布式在不同实例和不同的主机上,join将变得非常麻烦。而且基于架构规范,性能,安全性等方面考虑,一般是禁止跨库join的。那该怎么办呢?首先要考虑下垂直分库的设计问题,如果可以调整,那就优先调整。(就是尽量不要去分库)如果无法调整的情况,下面有几种解决方案:

1.全局表

所谓全局表,就是有可能系统中所有模块都可能会依赖到的一些表。比较类似我们理解的“数据字典”。为了避免跨库join查询,我们可以将这类表在其他每个数据库中均保存一份。同时,这类数据通常也很少发生修改(甚至几乎不会),所以也不用太担心“一致性”问题。

分库分表具体实施

1.停机迁移法

2.迁移历史数据,新的更新发kafka消息

就是对updatet_time小于某个时间点的数据全部拷贝出来,迁移到新的数据库,同时项目在执行增删改相关的SQL时,同时往Kafka中发一份,迁移结束后,用订阅程序消费kafka消息,更新新库,消费完之后,然后校验一致性切数据库。

缺点就算侵入性太强了,所有更新数据库的业务项目都需要改动,然后给kafka发消息。

3.迁移历史数据,订阅bin log接受更新

还是先迁移数据,迁移完之后用订阅程序消费bin log消息,更新新库,消费完之后,然后校验一致性,切数据库。

怎么验数据一致性

这里大概介绍一下吧,这篇的篇幅太长了,大家心里有底就行。 (1)先验数量是否一致,因为验数量比较快。 至于验具体的字段,有两种方法: (2.1)有一种方法是,只验关键性的几个字段是否一致。

随机取小批量数据,编码后比较。

(2.2)还有一种是 ,一次取50条(不一定50条,具体自己定,我只是举例),然后像拼字符串一样,拼在一起。用md5进行加密,得到一串数值。新库一样如法炮制,也得到一串数值,比较两串数值是否一致。如果一致,继续比较下50条数据。如果发现不一致,用二分法确定不一致的数据在0-25条,还是26条-50条。以此类推,找出不一致的数据,进行记录即可。


相关文章
|
27天前
|
SQL 存储 索引
12. 知道什么叫覆盖索引嘛 ?
**覆盖索引**是指在SQL查询中,索引包含所有所需列数据,避免回表查询,提高效率。创建覆盖索引可通过为查询字段建立联合索引,如在`user`表上为`name`和`age`创建`index_name_age`索引。查询`select name,age from user where name='Alice'`时,索引中已包含`name`和`age`,直接返回结果,实现覆盖索引。
19 0
12. 知道什么叫覆盖索引嘛 ?
|
8月前
|
存储 关系型数据库 MySQL
什么是覆盖索引?
本章主要讲解了索引覆盖和回表的相关知识
64 0
|
10月前
|
数据库 索引
覆盖索引
覆盖索引是指在数据库中创建一个索引,使得查询可以直接从索引中获取所需的数据,而不需要再去访问数据表。这种索引能够减少数据库的I/O操作,提高查询的性能。
45 0
|
8月前
|
存储 人工智能 测试技术
唯一索引比普通索引快吗?运行原理是什么?
唯一索引比普通索引快吗?运行原理是什么?
75 0
|
12月前
|
存储 关系型数据库 MySQL
|
12月前
|
SQL 关系型数据库 MySQL
好的索引当然是要覆盖了!
好的索引当然是要覆盖了!
|
Oracle 关系型数据库 索引
唯一约束和唯一索引区别
唯一约束和唯一索引区别
763 0
|
存储 SQL 关系型数据库
MySql索引详解-各种索引的定义与区别和应用
什么是索引?索引的作用,有无索引的区别。
152 0
MySql索引详解-各种索引的定义与区别和应用
测试关于索引的操作- 修改索引
测试关于索引的操作- 修改索引