索引应该采用什么存储结构?
使用B+Trees 树: 是分裂和合并的方式,底层是数组 + 双向指针 的方式。
树的深度是2 需要io的次数是3,永远是3次。
数据库还有hash 索引。 使用hash索引只能做等于的查询,不能使用大于小于等等。
优化器 (optimizer)
索引的分类:
普通索引:仅加速查询
唯一索引:加速查询 + 列值唯一(可以有null)
主键索引:加速查询 + 列值唯一(不可以有null)+ 表中只有一个
组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
全文索引:对文本的内容进行分词,进行搜索
聚集索引:
概念: 数据行的物理存放顺序和索引的逻辑的顺序相同,
定义:数据行的物理顺序与列值(一般是主键的那一列)的逻辑顺序相同,一个表中只能拥有一个聚集索引。
如果不创建索引,系统会自动创建一个隐含列作为表的聚集索引。
使用聚集索引的查询效率要比非聚集索引的效率要高,但是如果需要频繁去改变聚集索引的值,写入性能并不高,因为需要移动对应数据的物理位置。
非聚集索引在查询的时候可以的话就避免二次查询,这样性能会大幅提升。
不是所有的表都适合建立索引,只有数据量大表才适合建立索引,且建立在选择性高的列上面性能会更好。
联合索引 ( 最左原则) :
必须从第一个字段开始,中间不能中断,
先去匹配第一个字段匹配到了在去匹配第二个。
覆盖索引:
SQL只需要通过索引就可以返回查询所需要的数据,而不必通过二级索引查到主键之后再去查询数据。
就是你给某字段设置索引了,查询的时候 select 后面的字段 是设置索引的字段, 就是查的字段就是设置索引的字段就是 覆盖索引。
悲观锁(Pessimistic Lock)
顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。它指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。
乐观锁(Optimistic Lock)
顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。