[{"createTime":1735734952000,"id":1,"img":"hwy_ms_500_252.jpeg","link":"https://activity.huaweicloud.com/cps.html?fromacct=261f35b6-af54-4511-a2ca-910fa15905d1&utm_source=V1g3MDY4NTY=&utm_medium=cps&utm_campaign=201905","name":"华为云秒杀","status":9,"txt":"华为云38元秒杀","type":1,"updateTime":1735747411000,"userId":3},{"createTime":1736173885000,"id":2,"img":"txy_480_300.png","link":"https://cloud.tencent.com/act/cps/redirect?redirect=1077&cps_key=edb15096bfff75effaaa8c8bb66138bd&from=console","name":"腾讯云秒杀","status":9,"txt":"腾讯云限量秒杀","type":1,"updateTime":1736173885000,"userId":3},{"createTime":1736177492000,"id":3,"img":"aly_251_140.png","link":"https://www.aliyun.com/minisite/goods?userCode=pwp8kmv3","memo":"","name":"阿里云","status":9,"txt":"阿里云2折起","type":1,"updateTime":1736177492000,"userId":3},{"createTime":1735660800000,"id":4,"img":"vultr_560_300.png","link":"https://www.vultr.com/?ref=9603742-8H","name":"Vultr","status":9,"txt":"Vultr送$100","type":1,"updateTime":1735660800000,"userId":3},{"createTime":1735660800000,"id":5,"img":"jdy_663_320.jpg","link":"https://3.cn/2ay1-e5t","name":"京东云","status":9,"txt":"京东云特惠专区","type":1,"updateTime":1735660800000,"userId":3},{"createTime":1735660800000,"id":6,"img":"new_ads.png","link":"https://www.iodraw.com/ads","name":"发布广告","status":9,"txt":"发布广告","type":1,"updateTime":1735660800000,"userId":3},{"createTime":1735660800000,"id":7,"img":"yun_910_50.png","link":"https://activity.huaweicloud.com/discount_area_v5/index.html?fromacct=261f35b6-af54-4511-a2ca-910fa15905d1&utm_source=aXhpYW95YW5nOA===&utm_medium=cps&utm_campaign=201905","name":"底部","status":9,"txt":"高性能云服务器2折起","type":2,"updateTime":1735660800000,"userId":3}]
前面其实写了好几篇关于 mysql 索引的文章了,文章中有具体的实例和 sql 语句,这篇文章我想再用纯大白话讲讲 mysql 索引,文中不涉及具体 sql
。
我之前甚至想过为啥要用数据库来保存数据,用普通的 txt 或者 word
这类文件不行么,这个问题其实可以从几个方面来看,一个是并发访问数据加锁,另一个是数据安全性,再一个是数据的查询性能问题。这三个方面在 mysql
中都有对应的解决方案,比如事务、锁、日志系统(binlog、redolog 等)、索引。
为了实现高效查询,就得找到一种合适的数据结构来保存数据。首先我们可以想到使用哈希表,哈希表能通过键值快速找到对应的值,但是因为哈希是无序的,一般更适用于等值查询,但实际业务中通过会有大量的区间查询,比如查询
id 在 1-100 间的值,使用哈希的话效率就会大打折扣了。
那么就要找到一种既能满足等值查询,又能满足区间查询的数据结构了,又会很容易想到数组。数组可以通过下标快速找到对应的值,因为数组下标是有序的,所以通过遍历下标就能很高效的完成区间查询。
但是数组也有一个严重的问题,就是在删除或者插入数据的时候可能会移动大量其他数据,这是一个很大的性能消耗,所以数组一般更适合保存静态数据,比如一些历史数据,确定不会再更新的数据。
再一个就是二叉搜索树了,二叉搜索树的查找效率比较高,而且二叉搜索树的中序遍历就是一个有序数组,但依然不能很好的支持区间查询。
所以可以对二叉搜索树进行改造,树的节点不再保存具体数据,而是保存索引值,数据保存在最底层的叶子节点上,同时叶子节点间使用双链表连接起来,这样只需要先找到区间起始值的位置,然后往后遍历到终止值,即可完成区间查询。
事实上 mysql 底层采用的 B+ 树也就是这么一步步演变过来的,关于 B+ 树的详细介绍可以参考我前面的文章。
另外说一点,mysql
中有一个非常重要的模块,就是优化器,优化器的主要任务就是寻找一种更低代价方式去执行方式,通常会以扫描行数、是否需要排序、是否需要回表、是否需要临时表等来作为代价依据。
所以通常同一条 sql 在不同数据量的情况下执行情况可能会不一样,或者明明为某些 where
字段建立了索引,查询的时候偏偏又不走索引,这些情况其实都是经过优化器分析后作出的选择。因此你要知道,一条 sql 最终该怎么执行,还得看是在什么样的场景。