数据库索引,聚集索引,索引作用,索引常见模型

首先对于mysql索引,通过以下几个问题引入:
1、什么是索引?为什么数据库加了索引会查询变快?
2、什么情况下加索引比较好?能不能给所有的字段加索引?
3、什么情况下要同时在两个字段上建索引?
4、为什么加索引后会使写入、修改、删除变慢?
5、索引分为哪几类?分别有什么作用?
6、主键索引就是聚集索引吗?
7、索引常见的模型?InnoDB的索引模型?
8、索引使用策略以及优化?
9、InnoDB的主键选择与优化?
**

1、什么是索引?为什么数据库加了索引会查询变快?
从mysql基本存储结构来说,mysql基本存储结构是页,每个数据页是16KB,又分为文件头,文件尾,行记录等等。各个数据页可以组成一个双向链表。每个数据页中的记录又可以组成一个单向链表。所以如果不使用索引的情况下,想要查询一条数据,先遍历双向链表,找到所在的页,如果不是根据主键查询,再遍历所在页的单链表。而加了索引后,就会由无序变得有序了,通过“目录”,可以很快定位到对应的页上。其实底层结构就是B+树,通过二分查找,时间复杂度近似为O(logn)。
以我们平时建表时设置主键为例,主键其实就是一个索引,即聚集索引。如果一个表没加主键,它的数据无序的放置在磁盘存储器上,一行一行的排列很整齐,但同时查询起来要一条一条的去匹配数据量大时效率可想而知。如果给表上了主键,那么表在磁盘上的存储结构就由整齐排列转变成了树状结构。二分查找,效率大大提升。

2、什么情况下加索引比较好?能不能给所有的字段加索引?(参考:https://www.cnblogs.com/abcdwxc/p/9855474.html)
(1)表的主键、外键
(2)数据量超过300的表
(3)频繁与其他表建立连接的在该连接字段上加索引
(4)经常出现在Where子句中的字段 ,选择性高的字段上
(5)索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引
(6)频繁进行数据操作的表,不要建立太多的索引
(7)复合索引的建立需要进行仔细分析,尽量考虑用单字段索引代替
(8)删除无用的索引,避免对执行计划造成负面影响
不能将所有的字段都添加索引,因为:①索引会占用存储空间,索引越多,使用的存储空间越多,如果在大表上创建了多种组合索引,索引文件会增长很快②对表进行插入,更新,删除时,mysql不仅要保存数据,还要保存一下索引文件。

3、什么情况下要同时在两个字段上建索引?
当该字段作为查询条件,应用比较频繁时。

4、为什么加索引后会使写入、修改、删除变慢?
索引查询速度快,但是写入速度慢,因为平衡树结构要维持在一个正确的状态,增删改数据都会改变各个结点中的索引数据内容,破坏树结构。在每次数据改变时,DBMS必须去重新梳理该树(索引)结构来保证它的正确,这也会带来不小的性能开销。

5、索引分为哪几类?分别有什么作用?
①主键索引(加速查询 + 列值唯一(不可以有null)+ 表中只有一个)
ALTER TABLE table_name ADD PRIMARY KEY ( column )
②唯一索引(加速查询+列唯一(可以有null))
ALTER TABLE table_name ADD UNIQUE ( column )
③普通索引(仅加快查询)
ALTER TABLE table_name ADD INDEX index_name ( column )
④全文索引(对文本的内容进行分词,进行搜索)
ALTER TABLE table_name ADD FULLTEXT ( column)
⑤组合索引(多列值组成一个索引,专门用于组合搜索,其效率大于索引合并)
ALTER TABLE table_name ADD INDEX index_name ( column1, column2, column3 )
索引合并,使用多个单列索引组合搜索
覆盖索引,select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖

6、主键索引就是聚集索引吗?
根据叶子节点内容,索引分为主键索引和非主键索引,
在InnoDB里,主键索引也被称为聚集索引,非主键索引也被称为二级索引。
但是在myisam引擎里面主键也不是聚集索引,
在sql server中可以显示的指定聚集索引(主键的创建必须依赖于索引,默认创建的是聚集索引,但是可以在创建时声明为非聚集索引)。
聚集索引决定了数据库的物理存储结构,而主键只是确定了表格逻辑组织方式,两者不同。
InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶结点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是聚簇索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。
对于Innodb,主键毫无疑问是一个聚集索引。但是当一个表没有主键,或者没有一个索引,Innodb会如何处理呢。请看如下规则:(参考:https://www.cnblogs.com/lice-blog/p/11569443.html)
1.如果一个主键被定义了,那么这个主键就是作为聚集索引
2. 如果没有主键被定义,那么该表的第一个唯一非空索引被作为聚集索引
3. 如果没有主键也没有合适的唯一索引,那么innodb内部会生成一个隐藏的主键作为聚集索引,这个隐藏的主键是一个6个字节的列,改列的值会随着数据的插入自增。
4.自增主键会把数据自动向后插入,避免了插入过程中的聚集索引排序问题。聚集索引的排序,必然会带来大范围的数据的物理移动,这里面带来的磁盘IO性能损耗是非常大的。 而如果聚集索引上的值可以改动的话,那么也会触发物理磁盘上的移动,于是就可能出现page分裂,表碎片横生。所以不应该修改聚集索引。

7、索引常见的模型?InnoDB的索引模型?
实现索引方式有很多种,其中较为突出的为哈希表,有序数组和搜索树。
哈希表:适用于只有等值查询的场景,比如Memcached及其他一些NoSQL引擎。
有序数据:在等值查询和范围查询场景中的性能都非常优秀。但是如果更新数据,成本太高。索引有序数组只适用于静态存储引擎,比如存储某个城市人口信息。
在MySQL中,索引是在存储引擎层实现的,所以并没有统一的索引标准,即不同存储引擎的索引的工作方式并不一样。而即使多个存储引擎支持同一种类型的索引,其底层的实现也可能不同。由于InnoDB存储引擎在MySQL数据库中使用最为广泛,所以一般讨论InnoDB存储引擎,使用了B+树索引模型,所以数据都是存储在B+树中的,B+树能够很好地配合磁盘的读写特性,减少单次查询的磁盘访问次数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值