数据库是以一定方式储存在一起、能与多个用户共享、具有尽可能小的冗余度、与应用程序彼此独立的数据集合,可视为电子化的文件柜——存储电子文件的处所,用户可以对文件中的数据进行新增、查询、更新、删除等操作。
这两类索引在查询能力上是没差别的,主要考虑的是对更新性能的影响。建议尽量选择普通索引。
普通索引会多检索一次,几乎没有影响。因为 InnoDB 的数据是按照数据页为单位进行读写的,需要读取数据时,并不是直接从磁盘读取记录,而是先把数据页读到内存,再去数据页中检索。
一个数据页默认 16 KB
,对于整型字段,一个数据页可以放近千个 key
,除非要读取的数据在数据页的最后一条记录,就需要再读一个数据页,这种情况很少,对CPU的消耗基本可以忽略了。
因此说,在查询数据方面,普通索引和唯一索引没差别。
更新操作并不是直接对磁盘中的数据进行更新,是先把数据页从磁盘读入内存,再更新数据页。
由于 MySQL 中有个 change buffer
的机制,会导致普通索引
和唯一索引
在更新上有一定的区别。
change buffer
的作用是为了降低IO 操作
,避免系统负载过高。change buffer
将数据写入数据页的过程,叫做merge
。
如果需要更新的数据页在内存中时,会直接更新数据页;如果数据不在内存中,会先将更新操作记入change buffer
,当下一次读取数据页时,顺带merge
到数据页中,change buffer
也有定期merge
策略。数据库正常关闭的过程中,也会触发merge
。
对于唯一索引,更新前需要判断数据是否唯一(不能和表中数据重复),如果数据页在内存中,就可以直接判断并且更新,如果不在内存中,就需要去磁盘中读出来,判断一下是否唯一,是的话就更新。change buffer
是用不到的。即使数据页不在内存中,还是要读出来。
change buffer
用的是 buffer pool
里的内存,因此不能无限增大。change buffer 的大小,可以通过参数 innodb_change_buffer_max_size
来动态设置。这个参数设置为 50 的时候,表示 change buffer 的大小最多只能占用 buffer pool 的 50%。
结论:唯一索引
用不了change buffer
,只有普通索引
可以用。
change buffer
的作用是降低更新操作的频率,缓存更新操作。这样会有一个缺点,就是更新不及时,对于读操作比较频繁的表,不建议使用 change buffer。
因为更新操作刚记录进change buffer
中,就读取了该表,数据页被读到了内存中,数据马上就merge
到数据页中了。这样不仅不会降低性能消耗,反而会增加维护change buffer
的成本。
适用于写多读少的表。
我们举一个例子用来理解 redo log
和 change buffer
。我们执行以下 SQL 语句:
mysql> insert into t(id,k) values(id1,k1),(id2,k2);
假设,(id1,k1)
在数据页 Page 1 中,(id2,k2)
在数据页 Page 2 中。并且 Page 1 在内存中,Page 2 不在内存中。
执行过程如下:
(id1,k1)
;change buffer
中记下"向 Page 2 中写入(id2,k2)"
这条信息;做完上面这些,事务就可以完成了。执行这条更新语句的成本很低,就是写了两处内存,然后写了一处磁盘(两次操作合在一起写了一次磁盘),而且还是顺序写的。
这条更新语句,涉及了四个部分:内存、redo log(ib_log_fileX)、 数据表空间(t.ibd)、系统表空间(ibdata1)。
如果要读数据的话,过程是怎样的?
mysql> select * from t where k in (k1, k2);
假设读操作在更新后不久,此时内存中还有 Page 1,没有 Page 2,那么读操作就和 redo log
以及 ibdata1
无关了。
(id1,k1)
;merge
操作,此时内存中的 Page 2 也有最新数据(id2,k2)
;需要注意的是:
merge
操作,内存中的 Page 2 就是最新的了。)change buffer
中的数据分为两部分,一部分是已经merge
到ibdata1
中的数据,这部分数据已经持久化,不会丢失。另一部分数据,还在 change buffer
中,没有merge
到ibdata1
,分 3 种情况:commit
,binlog中也没有fsync到磁盘,这部分数据会丢失;commit
,binlog 已写入到磁盘,这部分不会多丢失,异常重启后会先从 binlog 恢复 redo log,再从 redo log 恢复 change buffer;redo log 主要节省的是随机写磁盘的 IO 消耗(转成顺序写),而 change buffer 主要节省的则是随机读磁盘的 IO 消耗
上一篇:网推外贸有哪些营销渠道?
下一篇:人工智能所需的所有概率基础
¥86.00
¥398.00
¥699.00
¥129.00
¥188.00