mysql联合索引怎么加 mysql创建多列索引的注意事项

hi 老兄,说到MySQL中的联合索引,我真的感触良多。
我记得有一年,我正在做一个电子商务项目,数据量令人望而生畏。
为了提高查询效率,我给订单表添加了公共索引。

当时我直接使用ALTER TABLE命令,添加了idx_customer_order_status的索引,并添加了customer_id、order_date、status三列。
我当时心里挺得意的,觉得自己的操作挺巧妙的。

但是后来我发现这个联合索引并不是那么好用。
首先你要遵循最左前缀原则,这一点我一开始就忽略了。
结果我曾经写过一个只有order_date和status的查询,发现根本没有使用索引,查询速度极其缓慢。

然后我发现列的顺序也很重要。
我把 customer_id 放在第一位,因为我理所当然地认为 customer_id 是唯一更有价值的。
当我后来优化结果时,我将订单日期向前移动,因为订单日期被更频繁地询问。

我们来谈谈多列索引和单列索引的选择。
有一次,为了查询特定用户的所有订单,我直接使用单列索引。
事实证明,合并这个索引的效率非常低,有时甚至比全表扫描还要慢。

创建索引时还必须小心,避免建立过多的索引,这会增加磁盘空间和维护成本。
我记得有一次我在一张表中添加了十几个索引。
结果写操作变得极其缓慢,最后不得不一一删除。

另外,不要忘记确认索引效果。
之前有一次,添加索引后,查询速度提高了,但后来发现有一个查询计划仍然使用全表扫描,最后不得不重新优化索引。

总之,创建常用索引时要注意方法、列顺序、选择策略,避免一些常见的误区。
我在这方面经历过很多陷阱,希望这些经验可以帮助你。
😅

为什么mysql索引需要遵循最左前缀匹配原则?

最左前缀原则是基础。

联合索引(a,b,c),必须使用a。

使用for查询,索引就会生效。

如果不使用a,则索引无效,并且会进行全表扫描。

前导列选择高分辨率列。

a 的区别最高,b 次之,c 排名最后。

但辨别力较高,低频场需谨慎使用。

选择高频、低分辨率字段。

MySQL8 .0.1 3 之后,有了SkipScan。

严格来说不是最左边的前缀,也可以使用索引。

通过范围扫描提高性能。

高度可区分的字段,受益于复杂的查询。

SkipScan 不是万能药。

受条件、索引类型和表大小影响。

索引设计和查询优化是关键。

自己掂量一下。

为什么 MySQL 优化器无法自动优化联合索引顺序,需要开发者遵循最左前缀原则?

是的,这就是问题所在。
MySQL优化器不会自动调整索引顺序,必须遵循最左原则。
为什么? 因为索引是按字段顺序排序的,如(user_id,created_at),所以先按user_id排序,再按created_at排序。
优化器只能从左到右搜索,没有user_id是没有用的。

优化器也不聪明。
默认为固定字段顺序,不会根据查询条件而改变。
因此,如果不遵循最左原则,就会放弃索引,进行全表扫描。

扫描全表太慢了,数据太多就悲剧了。
而且,指数维护也很费力,动态调整订单就更费力了。

最左原则也是有边界的。
例如,在(a,b,c)索引中,您可以检查a=1 ,但不能检查b=2
开发者必须根据业务需求设计索引,不要重新构建索引,如(status, create_time)和(create_time, status)。

总结就是优化器不智能,必须手动设计索引才能保证快速查询。
这样虽然比较麻烦,但是保证了性能。