请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

老师你好,数据库索引方面的问题,帮忙解答下,谢谢

老师你好,数据库索引方面的问题,帮忙解答下,问题描述如下:

课程中你提到,mysql InnoDB是以主键id来维护并创建的聚集索引树的,并建议主键id是递增的,这样可以提高数据插入的性能,因为递变的id可以减少在数据插入时导致的索引块拆分,我这里有两个问题一直想的不太明白:

1、就算是递增的id作为主键,插入数据时,当一个索引块存储满了,不也会引起索引块的拆分操作吗?这个递增的主键id是怎么增加数据的插入性能的呢?

2、表中如果还存在其它普通索引的话,那么这些索引对应的就都是非聚集索引,而且这些普通索引对应的列一般都是不能保证每次数据插入都递增的字符串,或者说每次插入的数据都是不能保证顺序的,不能像自增的主键id那样每次都是递增新插入一个,所以我感觉这个普通索引树仍然会存在插入记录时的性能问题,比如会导致索引块的拆分、旋转等复杂的索引树调整,但是现实中也没遇到这些性能问题啊,这不是跟使用随机的id作为数据库的主键一个道理了吗,难道是我理解错了?

正在回答

1回答

同学好,可以和杂乱无章的uuid进行对比。在存储和检索的时候,innodb会对主键进行物理排序,这对auto_increment_int是个好消息,因为后一次插入的主键位置总是在最后。但是对uuid来说,这却是个坏消息,因为uuid是杂乱无章的,每次插入的主键位置是不确定的,可能在开头,也可能在中间,在进行主键物理排序的时候,势必会造成大量的 IO操作影响效率,在数据量不停增长的时候,特别是数据量上了千万记录的时候,读写性能下降的非常厉害。

然后再来说说索引块的拆分,虽然索引块满了会引发索引块的拆分,但是有序的索引块的拆分会比无序的索引块拆分性能要好。

此外,同学说的非聚集索引,它锚定的是聚集索引的(叶子节点存储的是聚集索引),虽然它本身是无序的,但是相对于无序的非聚集索引锚定无序的聚集索引来说,索引块的拆分和树的调整性能也相对较小些:)

0 回复 有任何疑惑可以回复我~
  • 提问者 慕仔3163040 #1
    老师你好,非常感谢这么晚了还回复我的提问!
    我再追问一下,就是说一个表的普通索引,它对应的也就是mysql innodb的非聚集索引;因此其叶子节点存储的是主键id,由于普通索引一般都是有实际业务逻辑的列,那么我们每次对这个表做数据插入时,引擎都要先在主键索引或者说是聚集索引树里面插入这条记录,这个性能是很高的,因为自增的主键id每次都是最大的,然后再对这个普通索引树里面再插入一条记录?那这是不是就会出现你刚才说的那种情况:数据量过千万时,对普通索引树做数据插入的性能会下降的很严重?因为引擎在对普通索引树也就是非聚集索引树进行插入时,不能保证每次插入的数据对应的索引都在最后面
    回复 有任何疑惑可以回复我~ 2020-04-30 23:37:17
  • 翔仔 回复 提问者 慕仔3163040 #2
    同学好,这个确实是没法避免的,所以才会出现分表分库,从而提升性能
    回复 有任何疑惑可以回复我~ 2020-05-01 12:53:50
  • 提问者 慕仔3163040 回复 翔仔 #3
    好的,
    是不是可以这么理解:由于非聚集索引树的叶子节点只存储主键id不存储实际的行记录,相比聚集索引树而言,产生性能问题的可能性会小一些是吧?
    回复 有任何疑惑可以回复我~ 2020-05-01 17:14:40
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信