两分钟让你彻底明白MySQL聚簇索引和非聚簇索引

嘿,跟你唠唠 MySQL 这事儿,我当年也是干了不少蠢事,现在给你说道说道。

就说那聚簇索引吧。
我04 年刚入行那会儿,搞一个电商系统,表设计的时候没想明白。
用户表 user_id 是主键,聚簇索引。
结果呢?每次查用户信息,都得走聚簇索引。
后来发现,用户表巨多,每次查都要把整个用户信息都拉出来,卡得要死。
这教训,深刻啊。
聚簇索引,就是数据跟着索引走的,叶子节点就是数据本身。
你想想,表大了,数据都跟着走,那得占多大空间?还慢。
所以啊,设计表的时候,主键选得好不好,直接关系到查询效率。
当年我就是选了自增ID,结果用户信息一大堆,每次查都全拉出来,数据库CPU直接飙升。
后来改成了更散的ID,查询才快起来。

非聚簇索引,这玩意儿我接触得多。
07 年在做物流系统,订单表 order_id 是主键,聚簇索引。
然后有个查询需求,得根据快递单号查订单。
订单号不是主键,我就加了个非聚簇索引。
这索引叶子节点存的是主键 order_id。
你查的时候,先在非聚簇索引里找到 order_id,再回聚簇索引找数据。
这就像你记不住朋友电话,但知道他叫啥,通过名字翻电话本找到号。
不过啊,这有个坑,就是非聚簇索引如果太大,回表操作就多,也慢。
当年我就试过,一个索引几千个字段,查起来跟没索引似的。
所以啊,非聚簇索引,别乱加,加的时候要想清楚,它到底能帮你解决什么问题。

总的来说,聚簇索引就是数据本身,非聚簇索引是数据的指针。
你查数据的时候,如果索引是数据本身,那就快。
如果是指针,还得再走一遍。
当年我就是没想明白这点,搞了不少麻烦事。
现在设计表,先想清楚主键,再想想哪些字段需要快速查,加非聚簇索引。
别瞎加,不然得不偿失。

MySQL中的聚簇索引、非聚簇索引、联合索引和唯一索引

我记得有一次,我帮一个朋友的公司优化数据库查询,他们的数据库里有一个特别大的表,里面有几百万条记录。
这个表里有一个字段是用户名,每个用户名都是唯一的,所以他们为这个字段建立了一个唯一索引。

那天,我在办公室里,看到他们频繁地查询用户信息,每次查询都要好几分钟,非常慢。
我一开始以为是表太大导致的,但后来发现,他们的查询语句只涉及到用户名,也就是说,查询条件正好符合唯一索引的使用场景。

我试着修改了他们的查询语句,将查询条件改为联合索引中的前几个字段,结果查询速度瞬间提升了。
原来,他们之前的查询方式是先通过用户名找到主键,然后再去聚簇索引里找完整记录,这个过程叫“回表”,非常耗时。

我就在想,如果他们能更了解索引的类型和用法,是不是可以避免很多性能问题呢?比如,他们可以创建一个联合索引,包含用户名和需要查询的其他字段,这样查询速度会更快。

不过,我又突然想到,如果他们表中的字段非常多,创建联合索引的时候要注意索引的顺序,否则可能会影响查询效率。
这就像做饭一样,调料放对了顺序,味道才好。

所以,我就在想,是不是应该给他们做一次数据库的全面优化,不仅优化查询,还要优化索引结构,让数据库运行得更顺畅呢?

一文让你对mysql索引底层实现明明白白

那天在公园遛弯,看到一群小朋友在玩捉迷藏,他们总是能快速找到藏身之处,而那些不熟悉地形的大人却绕来绕去,走了很多冤枉路。
我突然想到,这不就是数据库索引的一个缩影吗?小朋友们就像数据库,他们能迅速找到所需的信息,而大人们则像没有索引的数据库,费时费力。
比如,我在数据库里找一个人,有索引和没索引的效率差,就像找朋友时,是直接找到他,还是到处乱撞。
这让我想起一个数字,如果是一百万条记录,没索引可能需要2 0次I/O,而有B+Tree索引的话,可能只需要3 次。
等等,还有个事,我在网上看到,有一种叫InnoDB的存储引擎,它通过聚簇索引,就像小朋友直接藏到了朋友家,减少了查找的麻烦。
不过,这种存储引擎在写入数据时可能就不那么高效了,因为每次写入都需要更新索引。
哎,这就像人生,有时候追求高效,就得付出一定的代价。