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。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)