索引(二)

查询过程

1,查询语句在索引树上查找过程,先通过B+树从树根开始按层搜索到叶子节点,数据页内部通过二分法定位记录。
1)对于普通索引,查找到满足条件的第一个记录后,需要查找下一个记录,直到第一个不满足条件的记录。
2)对于唯一索引,由于索引定义了唯一性,查询到第一个满足条件的记录后,就会停止搜索。

2,两种不同方式带来的性能差距比较小,InnoDB数据是按数据页为单位来读写的,当需要读一条记录时,不是将这条记录从磁盘读出,而是将这条记录的数据页整体读入内存。
1)InnoDB中,每个数据页的大小默认是16KB。
2)普通索引查找和判断下一条记录,只需要一次指针寻找和一次计算,但查找的记录刚好是数据页的最后一条记录,则取下一条记录时必须读取下一个数据页,操作稍微复杂一些。
3)对于整型字段,一个数据页可以存放近千个key,读取下一个数据页的概率比较低,所以在计算平均性能差异时忽略不计。

更新过程

1,更新语句,如果数据页在内存中直接更新,数据页不在内存中,在不影响数据一致性的前提下,InnoDB将更新缓存在change buffer中。
1)不从磁盘读入数据页,在下次查询需要访问数据页时再将数据页读入内存,然后执行change buffer中与数据页有关的操作,保证数据逻辑的正确性。
2)change buffer中的操作应用到原数据页的过程为merge,访问数据页会触发merge,系统后台线程也会定期merge,数据库正常关闭也会执行merge操作。

2,change buffer是可以持久化的数据,在内存中有拷贝,也会写入到磁盘。
1)数据读入内存需要占用buffer pool,使用change buffer可减少读磁盘,提升语句执行速度,还可避免占用内存,提高内存利用率。
2)change buffer占用的buffer pool的内存,大小可通过参数innodb_change_buffer_max_size动态设置,设置为50时,表示最多只能占buffer pool的50%。

change buffer
1,唯一索引不使用change buffer,普通索引使用。
1)唯一索引,所有的更新都要先判断索引的唯一性,例如插入数据时需要先判断表中key是否存在,则必须将数据页读入内存,没有冲突则插入数据,语句执行结束,也就没必要使用change buffer了。
2)普通索引可以使用change buffer,将更新记录在change buffer中,语句执行结束。

2,将数据从磁盘读入内存涉及随机IO的访问,是数据库中成本最高的操作之一,change buffer减少了随机磁盘的访问,对更新的性能提升比较明显。

3,merge才是真正数据更新过程,数据页merge之前,change buffer记录的变更越多,性能提升越明显。
1)在帐单类、日志类写多读少的业务中,页面写完立即访问的概率较小,change buffer使用效果佳。
2)业务更新之后立刻查询,更新记录在change buffer里,但立刻访问这个数据页触发merge过程,随机访问IO次数并不会减少,反而增加了change buffer的维护代价,可以关闭change buffer。
3)普通索引和唯一索引尽量选择普通索引,配合使用change buffer,更新优化明显。

change buffer和redo log
1,执行一条更新语句:
1)如果数据页在内存中,直接更新内存同时记录到redo log,之后执行查询操作直接从内存返回;
2)如果数据页不在内存中,将更新记录到内存change buffer区域,并记录到redo log中,之后执行查询操作,需要从磁盘读入数据页到内存,再应用change buffer操作,最后返回正确结果。

2,一条更新语句插入多个记录,按以上原则写到内存或change buffer中,写了两处内存,多条记录顺序写入redo log,写一次磁盘。

3,redo log主要节省随机写磁盘的IO消耗(转成顺序写),change buffer主要节省随机读磁盘的IO消耗。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL中的一级索引又称为聚集索引,通常是主键索引。一级索引索引和数据存储在一起,存储在同一个B树中的叶子节点。当使用一级索引进行查询时,可以直接定位到数据行。例如,在一个表中使用id作为主键创建了一级索引,当执行`SELECT * FROM table WHERE id = 1;`时,只需要读取少量磁盘块就可以获取到对应的数据。 而索引又称为非聚集索引或次要索引,是在一级索引之外创建的索引,用于提高非主键列的查询性能。索引通常包含索引列和指向数据行的指针,可以通过索引列快速定位到数据行。当使用索引进行查询时,首先通过索引找到对应的主键值,然后再使用一级索引找到对应的数据记录。例如,如果根据字段plname创建了索引,在执行`SELECT * FROM pl_ranking WHERE plname = 'Java';`时,首先通过索引找到Java对应的主键id,然后再通过一级索引找到对应的数据行。 因此,使用索引需要进行"回表"操作,即需要额外的一次查找。 一级索引索引之间的关系是,一级索引可以单独存在,而索引必须依附于一级索引索引存储的是主键值而不是实际的数据,这样可以减少数据冗余和维护工作。优点是减少了数据冗余,减少了行移动或数据页分裂时索引的维护工作。缺点是根据索引查找行的完整数据需要进行额外的回表操作。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [一级索引索引 的概念及使用](https://blog.csdn.net/m0_69057918/article/details/131066870)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [MySQL的一级索引索引介绍](https://blog.csdn.net/weixin_43606861/article/details/116202806)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值