「MySQL高级篇」MySQL索引原理,设计原则( 四 )


  1. 按楼梯从低到高,无出现跳跃的情况--此时符合最左前缀原则,索引不会失效

「MySQL高级篇」MySQL索引原理,设计原则

文章插图
  1. 出现跳跃的情况
  • 直接第一层name都不走,当然都失效

「MySQL高级篇」MySQL索引原理,设计原则

文章插图
  • 走了第一层,但是后续直接第三层,只有出现跳跃情况前的不会失效(此处就只有name成功)

「MySQL高级篇」MySQL索引原理,设计原则

文章插图
  • 同时 , 这个顺序并不是由我们where中的排列顺序决定,比如:
    • where name='小米科技' and status='1' and address='北京市'
    • where status='1' and name='小米科技' and address='北京市'
这两个尽管where中字段的顺序不一样 , 第二个看起来越级了,但实际上效果是一样的
其实是因为我们MySQL有一个Optimizer(查询优化器),查询优化器会将SQL进行优化,选择最优的查询计划来执行 。
  • 关于这个查询优化器,后续文章我们也会谈谈MySQL的逻辑架构与存储引擎
索引设计原则针对表
  1. 查询频次高,且数据量多的表
针对字段
  1. 最好从where子句的条件中提取 , 如果where子句中的组合比较多,那么应当挑选最常用、过滤效果最好的列的组合 。
其他原则
  1. 最好用唯一索引,区分度越高,使用索引的效率越高
  2. 不是越多越好,维护也需要时间和空间代价,建议单张表索引不超过 5 个
因为 MySQL 优化器在选择如何优化查询时,会根据统一信息,对每一个可以用到的索引来进行评估 , 以生成出一个最好的执行计划,如果同时有很多个索引都可以用于查询,就会增加 MySQL 优化器生成执行计划的时间,同样会降低查询性能 。
比如:
我们创建了三个单列索引,name , status,address
当我们where中根据status和address两个字段来查询时,数据库只会选择最优的一个索引,不会所有单列索引都使用 。最优的索引:具体是指所查询表中 , 辨识度最高(所占比例最少)的索引列,比如此处address中有一个辨识度很高的 '西安市'数据;
「MySQL高级篇」MySQL索引原理,设计原则

文章插图
?
  1. 使用短索引,索引创建之后也是使用硬盘来存储的 , 因此提升索引访问的I/O效率,也可以提升总体的访问效率 。假如构成索引的字段总长度比较短,那么在给定大小的存储块内可以存储更多的索引值,相应的可以有效的提升MySQL访问索引的I/O效率 。
  2. 利用最左前缀 , 比如有N个字段,我们不一定需要创建N个索引,可以用复合索引
也就是说 , 我们尽量创建复合索引,而不是单列索引
创建复合索引: CREATE INDEX idx_name_email_status ON tb_seller(name,email,status);就相当于 对name 创建索引 ; 对name , email 创建了索引 ; 对name , email, status 创建了索引 ;举个栗子假设我们有这么一个表,id为主键,没有创建索引:
CREATE TABLE `tuser` (`id` int(11) NOT NULL,`name` varchar(32) DEFAULT NULL,`age` int(11) DEFAULT NULL,PRIMARY KEY (`id`),) ENGINE=InnoDB如果要在此处建立复合索引,我们要遵循什么原则呢??
通过调整顺序,可以少维护一个索引
  • 比如我们的业务需求里边 , 有如下两种查询方式:
    1. 根据name查询
    2. 根据name和age查询
如果我们建立索引(age,name),由于最左前缀原则 , 我们这个索引能实现的是根据age , 根据age和name查询,并不能单纯根据name查询(因为跳跃了),为了实现我们的需求,我们还得再建立一个name索引;?
而如果我们通过调整顺序,改成(name,age),就能实现我们的需求了,无需再维护一个name索引 , 这就是通过调整顺序,可以少维护一个索引 。
考虑空间->短索引
  • 比如我们的业务需求里边,有以下两种查询方式:
    1. 根据name查询
    2. 根据age查询
    3. 根据name和age查询
我们有两种方案:
  1. 建立联合索引(name,age),建立单列索引:age索引 。
  2. 建立联合索引(age,name),建立单列索引:name索引 。
?
这两种方案都能实现我们的需求 , 这个时候我们就要考虑空间了,name字段是比age字段大的 , 显然方案1所耗费的空间是更小的,所以我们更倾向于方案1 。

推荐阅读