在mysql中,索引是一种特殊的数据库结构,由数据表中的一列或多列组合而成,可以用来快速查询数据表中有某一特定值的记录。
通过索引,查询数据时不用读完记录的所有信息,而只是查询索引列即可。
通过索引,查询数据时不用读完记录的所有信息,而只是查询索引列。否则,数据库系统将读取每条记录的所有信息进行匹配。
可以把索引比作新华字典的音序表。例如,要查“库”字,如果不使用音序,就需要从字典的 400 页中逐页来找。但是,如果提取拼音出来,构成音序表,就只需要从 10 多页的音序表中直接查找。这样就可以大大节省时间。
因此,使用索引可以很大程度上提高数据库的查询速度,还有效的提高了数据库系统的性能。
索引的优缺点
索引有其明显的优势,也有其不可避免的缺点。
优点
索引的优点如下:
1、通过创建唯一索引可以保证数据库表中每一行数据的唯一性。
2、可以给所有的 MySQL 列类型设置索引。
3、可以大大加快数据的查询速度,这是使用索引最主要的原因。
4、在实现数据的参考完整性方面可以加速表与表之间的连接。
5、在使用分组和排序子句进行数据查询时也可以显著减少查询中分组和排序的时间
缺点
增加索引也有许多不利的方面,主要如下:
1、创建和维护索引组要耗费时间,并且随着数据量的增加所耗费的时间也会增加。
2、索引需要占磁盘空间,除了数据表占数据空间以外,每一个索引还要占一定的物理空间。如果有大量的索引,索引文件可能比数据文件更快达到最大文件尺寸。
3、当对表中的数据进行增加、删除和修改的时候,索引也要动态维护,这样就降低了数据的维护速度。
使用索引时,需要综合考虑索引的优点和缺点。
字符串创建索引方式:
1、直接创建完整索引,比较占用空间。
2、创建前缀索引,节省空间,但会增加查询扫描次数,并且不能使用覆盖索引。
3、倒序存储,在创建前缀索引,用于绕过字符串本身前缀的却分度不够的问题。
4、创建hash字段索引,查询性能稳定,有额外的存储和计算消耗。
倒序存储和hash字段索引都不支持范围查询。倒序存储的字段上创建的所有是按照倒序字符串的方式排序的。hash字段的方式也只能支持等值查询。
mysql>alter table SUser add index index1(email):包含了每个记录的整个字符串
或
mysql>alter table SUser add index index2(email(6)):-对于每个记录只取前6个字节
全字段索引 *** 作流程
使用的是 index1(即 email 整个字符串的索引结构),执行顺序是这样的:
1、从 index1 索引树找到满足索引值是’ [email protected] ’的这条记录,取得 ID2 的值;
2、到主键上查到主键值是 ID2 的行,判断 email 的值是正确的,将这行记录加入结果集;
3、取 index1 索引树上刚刚查到的位置的下一条记录,发现已经不满足 email=' [email protected] ’的条件了,循环结束。
前缀字段索引 *** 作流程
如果使用的是 index2(即 email(6) 索引结构),执行顺序是这样的:
1、从 index2 索引树找到满足索引值是’zhangs’的记录,找到的第一个是 ID1;
2、到主键上查到主键值是 ID1 的行,判断出 email 的值不是’ [email protected] ’,这行记录丢弃;
3、取 index2 上刚刚查到的位置的下一条记录,发现仍然是’zhangs’,取出 ID2,再到 ID 索引上取整行然后判断,这次值对了,将这行记录加入结果集;
4、重复上一步,直到在 idxe2 上取到的值不是’zhangs’时,循环结束。
倒序查询和hash字段的区别
它们的区别,主要体现在以下三个方面:
1、从占用的额外空间来看,倒序存储方式在主键索引上,不会消耗额外的存储空间,而 hash 字段方法需要增加一个字段。当然,倒序存储方式使用 4 个字节的前缀长度应该是不够的,如果再长一点,这个消耗跟额外这个 hash 字段也差不多抵消了。
2、在 CPU 消耗方面,倒序方式每次写和读的时候,都需要额外调用一次 reverse 函数,而 hash 字段的方式需要额外调用一次 crc32() 函数。如果只从这两个函数的计算复杂度来看的话,reverse 函数额外消耗的 CPU 资源会更小些。
3、从查询效率上看,使用 hash 字段方式的查询性能相对更稳定一些。因为 crc32 算出来的值虽然有冲突的概率,但是概率非常小,可以认为每次查询的平均扫描行数接近 1。而倒序存储方式毕竟还是用的前缀索引的方式,也就是说还是会增加扫描行数。
字符串加索引的方式?
对于字符串进行添加索引,我们除了对整个字符串加索引以外,还可以添加前缀索引。
什么是前缀索引?
前缀索引的好处?
使用前缀索引,定义好长度,可以做到即节省空间,又不用额外增加太多的查询成本。
前缀索引的弊端?
前缀索引会使覆盖索引失效,额外增加回表的消耗,如果前缀索引的长度选择区分度不高,会额外导致扫描行数增加。
其他给字符串加索引的方式?
什么是脏页?
MySQL在更新数据的时候会写redo log并且更新内存以后就会返回,数据文件并不会立即更新,这就是所谓的WAL机制。
当内存被更新以后,内存中的数据页就会和磁盘上的数据页存在不一致的情况,该内存也就被称为 脏页 。
内存中的数据被写入磁盘以后,内容变为一致,此时该内存页就被称为干净页。
什么叫刷脏页?
内存数据页中的内容被写入磁盘数据页中的过程称为刷脏页。
什么时候会刷脏页?
InnoDB如何控制刷脏页的频率?
首先确认InnoDB所在主机的IO能力,此时需要用到数据库的innodb_io_capacity参数,该参数推荐设置为磁盘的IOPS。磁盘的IOPS可以通过fio工具进行测试。
InndoDB刷脏页主要考虑以下两个因素:
MySQL会根据F1(M)和F2(N)两个值,取其中较大的值记为R,之后引擎可以按照innodb_io_capacity定义的能力乘以R%来控制刷脏页的速度。
脏页比例
参数innodb_max_dirty_pages_pct是脏页比例的上限,MySQL 8.0中是90%。
当前脏页比例可以通过Innodb_buffer_pool_pages_dirty/Innodb_buffer_pool_pages_total计算获得,具体sql计算指令如下:
连坐机制
InnoDB在刷脏页的时候,如果该脏页旁边的是页也是脏页,会同时把相邻的脏页刷掉。
该刷脏页行为由参数innodb_flush_neighbors控制:
对于机械硬盘,开启连坐会减少随机IO的消耗,但对于SSD,没必要开启该参数。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)