mysql索引

mysql索引,第1张

二叉搜索树、N叉树

页分裂: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

表button 

CREATE TABLE `button` (

  `id` bigint(20) NOT NULL AUTO_INCREMENT,  --主键索引

  `button_name` varchar(45) NOT NULL COMMENT '功能名称',

  `app_id` bigint(20) NOT NULL,

  `permission_id` bigint(20) DEFAULT NULL,  -- permission_id 和 app_id 联合索引。

  `api_id` bigint(20) NOT NULL, --api_id单独索引

  PRIMARY KEY (`id`),

  KEY `index_app_permission_lianhe` (`permission_id`,`app_id`) USING BTREE,

  KEY `index_api_id_dange` (`api_id`)

) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

主键索引,单独索引,组合索引使用场景及优化

表button 有3个索引,分别是:id主键,联合索引(permission_id,app_id),api_id(单列索引)

button_name 无索引

查询where条件中:

主键索引:

1、主键索引与联合索引同时存在,使用主键索引

2、主键索引与单个索引同时存在,使用主键索引

结论:只要主键索引在,使用主键索引。

联合索引 :

1、联合索引与单列索引列 同时存在,使用单列索引

2、联合索引中列顺序颠倒无影响。

3、联合索引实行最左侧原则,即:单独查询条件中只有permission_id可以使用联合索引,单独查询条件中只有app_id不实用联合索引。

4、如果查询条件中只有app_id,但是select 条件中有 permission_id,则也使用联合索引。

5、select id,app_id from button where app_id=1001使用联合索引

6、explain select id,app_id,button_name from button where app_id=1001不使用联合索引

结论:索引优先级:主键索引,单列索引,组合索引

    联合索引中遵从最左侧列原则。

    当查询条件和返回结果中仅仅包含联合索引中索引项,也使用联合索引。如第4条。

    当查询条件中出现联合索引中非最左侧索引列,返回结果中含义联合索引中的列或者主键则也使用联合索引。

单个索引:

1、查询条件中有单列索引,则使用,无不使用。

事例:

主键一般有几种选择:

一般DBA会推荐InnoDB表必须建主键,而且推荐使用整型的自增主键。

三种选择的优先级是 自增id >业务整型字段 >UUID。

如果使用UUID作为主键,那么B+树的聚集索引的key就是UUID,UUID通常会比整型字段要长,而且字符串的比较是需要逐个字节比较,所以得出两个缺点

比起自增id,虽然都是整型,但是业务字段有可能不是按顺序插入到表,考虑下图。

此时要插入索引值为4的节点,而B+树每页最多存放两个节点,插入4节点后,树变为

B+树特点是,所有节点从左右往右排好序,自增id插入B+是有序的,只会在节点放满了之后,才会新增一个页去存放,比起非自增id,会减少页分裂次数,提高性能。

对非主键进行索引,就是普通索引。

与聚集索引一样,每个普通索引建立后,会用一个B+树进行维护,但是叶子节点并非存储索引对应行的所有记录,而是只存储了主键值,此时得到主键值后,再回到聚集索引上查找一次,即可得到数据记录,即回表。

这个不带行数据完整信息的索引,就叫二级索引(secondary index),也叫辅助索引。

对多个字段同时建索引,就是联合索引。

当查询条件同时涉及多个字段,就可以使用联合索引。

联合索引会根据字段的出现顺序在B+树中排好序,例如先入name排序,当name相同时就使用age,直到比较出大小为止。 利用这个特性,可以使用最左前缀原则优化SQL。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/7170801.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-02
下一篇 2023-04-02

发表评论

登录后才能评论

评论列表(0条)

保存