页分裂:B+树的插入可能会引起数据页的分裂,删除可能会引起数据页的合并,二者都是比较重的IO消耗,所以比较好的方式是顺序插入数据,这也是我们一般使用自增主键的原因之一。
页分裂逆过程:页合并,当删除数据后,相邻的两个数据页利用率很低的时候会做数据页合并
主键索引:key:主键,value:数据页,存储每行数据
非主键索引:key:非主键索引,value:主键key,导致回表
最左匹配:优先将区分度高的列放到前面,这样可以高效索引,
最左匹配原则遇到范围查询就停止匹配,范围查询(>、<、between、like)为什么?因为出现范围匹配后,后面的索引字段无法保证有序,局部有序失去,顺序失去则无法提高查询效率
SELECT * FROM table WHERE a IN (1,2,3) and b >1
如何建立索引?
还是对(a,b)建立索引,因为IN在这里可以视为等值引用,不会中止索引匹配,所以还是(a,b)!
索引组织表
索引用页存储:key【10】-point【6】,通过调整key大小,当页大小固定的情况下,通过调整key大小,使得N叉树变化;
如key 10, point 6则单个索引16字节,页大小为16k,则页面总共可以存储1024个索引,即N大小
覆盖索引: 二级索引的信息已经存在想要的列,例如主键
如果现在有一个高频请求,要根据市民的身份z号查询他的姓名,这个联合索引就有意义了。它可以在这个高频请求上用到覆盖索引,不再需要回表查整行记录,减少语句的执行时间。
索引下推优化:可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数。
整理索引碎片,重建表:alter table T engine=InnoDB
首先是看key的大小,另外是数据页的大小,如果需要改变N,则需要从这两个方面做改动;
一个innoDB引擎的表,数据量非常大,根据二级索引搜索会比主键搜索快,文章阐述的原因是主键索引和数据行在一起,非常大搜索慢,我的疑惑是:通过普通索引找到主键ID后,同样要跑一边主键索引,对于使用覆盖索引的情况下,使用覆盖索引可以直接解决问题
https://blog.csdn.net/itworld123/article/details/115144202
https://time.geekbang.org/column/article/69236
https://zhuanlan.zhihu.com/p/334684710
https://www.cxyzjd.com/article/pyzhizhuren/88431380
https://www.jianshu.com/p/4277d9dd0a9f
https://www.cnblogs.com/rjzheng/p/12557314.html
https://mengkang.net/1302.html
https://note.cser.club/database/bi-xu-le-jie-de-mysql-san-da-ri-zhi-binlogredo-log-he-undo-log
https://cloud.tencent.com/developer/news/44861
在mysql数据库中为字段添加索引,意思是对数据库某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页进行排序,它是逻辑指针清单。
索引提供指向存储在表的指定列中的数据值的指针,然后根据指定的排序顺序对这些指针排序。数据库使用索引以找到特定值,然后顺指针找到包含该值的行。这样可以使对应于表的SQL语句执行得更快,可快速访问数据库表中的特定信息。
扩展资料:
当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在employee表中职员的姓(lname)上创建了唯一索引,则任何两个员工都不能同姓。
对某个列建立UNIQUE索引后,插入新记录时,数据库管理系统会自动检查新纪录在该列上是否取了重复值,在CREATETABLE命令中的UNIQE约束将隐式创建UNIQUE索引。
MySQL 前缀索引能有效减小索引文件的大小,提高索引的速度。但是前缀索引也有它的坏处:MySQL 不能在 ORDER BY 或 GROUP BY 中使用前缀索引,也不能把它们用作覆盖索引(Covering Index)。
集一个索引包含多个列(最左前缀匹配原则)
索引列的值必须唯一,但允许有空值
全文索引为FUllText,在定义索引的列上支持值的全文查找,允许在这些索引列中插入重复值和空值,全文索引可以在CHAR,VARCHAR,TEXT类型列上创建
设定主键后数据会自动建立索引,InnoDB为聚簇索引
即一个索引只包含单个列,一个表可以有多个单列索引
覆盖索引是指一个查询语句的执行只用从所有就能够得到,不必从数据表中读取,覆盖索引不是索引树,是一个结果,当一条查询语句符合覆盖索引条件时候,MySQL只需要通过索引就可以返回查询所需要的数据,这样避免了查到索引后的回表 *** 作,减少了I/O效率
查看索引
列名解析:
删除索引
查看:
删除前:
删除后:
普通的索引,没有什么介绍
查看:(注意和前缀索引Sub_part的区别)
当索引的列是unique的时候,会生成唯一索引,唯一索引关于null有下列两种情况
SQLSERVER 下的唯一索引的列,允许null值,但最多允许有一个空值
MYSQL下的唯一索引的列,允许null值,并且允许多个空值
查看:
会建立两个索引,一个非聚簇索引,一个是唯一索引
结果:
可以插入两个空值(明人不说暗话,我喜欢MySQL)
一方面,它不会索引所有字段所有字符,会减小索引树的大小.
另外一方面,索引只是为了区别出值,对于某些列,可能前几位区别很大,我们就可以使用前缀索引。
一般情况下某个前缀的选择性也是足够高的,足以满足查询性能。对于BLOB,TEXT,或者很长的VARCHAR类型的列,必须使用前缀索引,因为MySQL不允许索引这些列的完整长度。
查看:
查看:
复合索引的最左前缀匹配原则 :
对于复合索引,查询在一定条件才会使用该索引
减少开销。 建一个联合索引(col1,col2,col3),实际相当于建了(col1),(col1,col2),(col1,col2,col3)三个索引。每多一个索引,都会增加写 *** 作的开销和磁盘空间的开销。对于大量数据的表,使用联合索引会大大的减少开销!
覆盖索引。 对联合索引(col1,col2,col3),如果有如下的sql: select col1,col2,col3 from test where col1=1 and col2=2。那么MySQL可以直接通过遍历索引取得数据,而无需回表,这减少了很多的随机io *** 作。减少io *** 作,特别的随机io其实是dba主要的优化策略。所以,在真正的实际应用中,覆盖索引是主要的提升性能的优化手段之一。
效率高。 索引列越多,通过索引筛选出的数据越少。有1000W条数据的表,有如下sql:select from table where col1=1 and col2=2 and col3=3,假设假设每个条件可以筛选出10%的数据,如果只有单值索引,那么通过该索引能筛选出1000W10%=100w条数据,然后再回表从100w条数据中找到符合col2=2 and col3= 3的数据,然后再排序,再分页;如果是联合索引,通过索引筛选出1000w10% 10% *10%=1w。
在模糊搜索中很有效,搜索全文中的某一个字段,可以参考这篇博文
: https://zhuanlan.zhihu.com/p/88275060
我们先进行下面一个实验看看InnoDB下的主键索引的一个现象。
查看:
我们插入进去的时候,数据的id都是乱序的,为什么这里最后select查询出来的结果都是进行了排序?
这是因为InnoDB索引底层实现的是B+tree,B+tree具有下列的特点:
所以上面的排序是为了使用B+tree的结构 ,B+tree为了范围搜索,将主键按照从小到大排序后,拆分成节点。后续还有新的节点进入的时候,和B-tree相同的 *** 作,会进行分裂。
一般来说,聚簇索引的B+tree都是三层
InnoDB中主键索引一定是聚簇索引,聚簇索引一定是主键索引。
为什么这里辅助索引叶子结点不直接存储数据呢?
MYISAM只有非聚簇索引,索引最终指向的都是物理地址。
Q:既然有回表的存在,那么聚簇索引的优势在哪里?
Q:主键索引作为聚簇索引需要注意什么
在查询语句中使用LIke关键字进行查询时,如果匹配字符串的第一个字符为"%",索引不会使用。如果“%”不是在第一位,索引就会使用
多列索引是在表的多个字段上创建的索引,满足最左前缀匹配原则,索引才会被使用
查询语句只有Or关键字时候,如果OR前后的两个条件都是索引,这这次查询将会使用索引,否则Or前后有一个条件的列不是索引,那么查询中将不使用索引
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)