我对DB***的理解,数据库的构成:存储+实例不用多说,数据当然要存储;storage是不够的,显然需要提供一个程序,对storage的操作进行封装,对外提供增删改查的API,即实例。一个存储可以对应多个实例,提高存储的负载能力和高可用性;多个存储可以分布在不同的机房和区域,实现容灾。二、按Block或Page读取数据用大腿就知道数据库不可能按行读取数据(Why?^_^)。本质上,Oracle/MySQL等数据库都是基于固定大小(如16K)的物理块(Block或Page,这里不做区分,统称为Block)来实现调度和管理。要知道块是数据库的一个概念,那它和文件系统是怎么对应的呢?显然,有必要指出“这个块的地址在哪里”。当找到地址后,读取固定大小的数据就相当于完成了块的读取。数据库非常智能。它不仅会读取需要读取的块,还会为我们读取附近的块并将其加载到内存中。其实这是为了减少IO的数量,提高效率。事实上,一个区块的附近区块也是热点数据。这个处理方法很有必要!第三,磁盘IO是数据库的性能瓶颈。毫无疑问,数据在磁盘上,磁盘IO是少不了的。磁头旋转、轨道定位、寻址的过程就不说了。我们是程序员,我们无法控制这些。但是这个过程确实非常耗时,而且和内存读取不是一个数量级的,所以出现了很多减少IO,提高数据库性能的方法。例如,增加内存允许数据库将更多数据加载到内存中。记忆力虽好,但不能滥用。你为什么这么说?假设数据库中有100G的数据。如果全部加载到内存中,意味着数据库要管理100G的磁盘数据+100G的内存数据。你累了吗?(数据库需要处理磁盘和内存的映射关系,数据同步,清理内存数据,如果涉及到数据库事务,就是一系列复杂的操作。。。)但是这里需要指出的是,在为了加快内存查找速度,数据库一般会对内存进行HASH存储。比如使用索引,与内存相比,索引是一个非常划算的东西。下面的文章将详细介绍MySQL的索引原理。比如使用性能更好的磁盘...(跟我们没关系)四、提出一些问题思考:为什么说用delete删除表的数据比transcateatable慢?[按行查找删除,多费力气;aBlock-basedarchitecturedelete]为什么说小表驱动大表?【小表驱动大表会更快?我勒个去?M*N和N*M不一样吗?有鬼,有索引!】探究MySQL索引背后的原理对于绝大多数应用系统来说,读写比都是10:1,甚至100:1,insert/update很难做到有性能问题。遇到最多,最难最重要的就是select,select优化最重要,显然索引是少不了的!说到MySQL索引,我们会有很多这样的东西:BTree索引/B+Tree索引/Hash索引/聚集索引/非聚集索引...这么多,晕!索引到底是什么,要解决什么问题?这是陈词滥调。官网说MySQL索引是一种数据结构,建立索引的目的是为了提高查询效率。说白了,如果不使用索引,磁盘IO次数比较多!想减少磁盘IO次数怎么办?我们想通过不断缩小想要获取的数据范围来筛选出最终想要的结果,并且将每次搜索数据的磁盘IO次数控制在一个较小的数量级,最好是恒定的数量级。为了解决以上问题,B+Tree索引就出来了!你好,MySQL中的B+Tree,不同的存储引擎实现索引的方式不同。这里我们重点分析MyISAM和Innodb。MyISAM引擎的B+Tree索引结构我们知道对于MyISAM引擎来说,数据文件和索引文件是分开的。从图中也可以看出,通过索引查找后,得到了数据的物理地址,然后可以根据地址定位到数据文件中的记录。这种方法也称为“非聚集索引”。对于Innodb引擎来说,数据文件本身就是一个索引文件!通俗地说,在叶子节点上,MyISAM存放的是记录的物理地址,而Innodb存放的是数据内容。这种方法称为“聚集索引”。还有一点需要注意的是,对于Innodb来说,主键索引中的叶子节点存放的是数据内容,而普通索引的叶子节点存放的是主键值!也就是说,对于Innodb的普通索引字段查找,先通过普通索引的B+Tree找到主键后,再通过主键索引的B+Tree查找。从这里可以看出对于Innodb来说,主键的建立是非常重要的!对于MyISAM,主键索引和普通索引的唯一区别是主键只需要找到一条记录就停止,而普通索引允许重复。找到一条记录后,需要继续查找,结构上没有区别,如上图所示。深入B+Tree,问几个问题:为什么B+Tree要把真正的数据放在叶子节点而不是内部节点?为什么说索引字段越短越好,而***是单调递增的呢?为什么要存在复合索引?最左匹配原则?范围查询(>,先不玩B+Tree的一些数学理论,至少有一点是可以确定的:数据表的数据量N=F(树的高度h,每个Block存储的索引个数m).当N一定时,索引字段越小,m越大,也就是说h越小!树越低,当然查找速度会越快!如果内节点存储real显然,m会更小,树会更高。在实际应用中,我们应该尽可能使用单调递增的字段作为主键,一方面不会让索引的数据结构变大,减少占用的空间;另一方面,不会频繁拆分B+Tree,这样会降低效率,比如复合索引(name,age,sex),B+Tree会先比较name来确定下一个搜索方向。如果突然出现一个(年龄,性别),就无从下手了。这也符合commo感觉。对于一本书,我们说“在哪一章哪一节找到XXX”,却从来没有听说过“在哪一节找到XXX”!这是复合索引的一个重要特征,即最左匹配特征。假设有一个复合索引(name,age,sex),我们在select的时候,不按照这个顺序,而是sex='man'andname='zfz'andage=27,会用到这个索引吗?数据库很聪明,SQL优化的时候会自动帮我们调整!但是如果缺少了复合索引的***列,数据库就无能为力了。对于最左边的匹配,MySQL会一直向右匹配,直到遇到范围查询停止匹配。这是什么意思?比如一个复合索引(name,age,sex),对于name='zhangfengzhe'andage>26andsex='man',其实只是用到了复合索引的name列。如果要使用索引,则必须“干净”。什么是“干净”?只是不要让指数参与计算!例如,将函数应用于索引可能会导致索引变得无效。为什么?其实不用想。B+Tree存储数据。如果要比较,则需要将函数应用于所有数据。显然,成本太高了。如果要建立索引,请看判别索引。虽然物美价廉,但也不要乱来。count(distinctcol)/count(*)可以计算出col的区分度,显然对于主键来说,就是1。如果区分度太低,可以考虑是否需要建索引?Hash索引并不是要深入分析Hash索引,只是说明一下Hash的思想真的是无处不在!在MySQLMemory存储引擎中,有一个hash函数,给定一个key,通过hash函数计算出地址,所以一般情况下,hash索引查找会很快,O(1)的速度。但是也有hash冲突,和HashMap一样,都是以单链表的形式来解决的。想一想,哈希索引支持范围查询吗?显然不是,只能搜索一个KEY。就像HashMap一样,找到包含“zhangfengzhe”的key会不会很快?这里给大家推荐一个架构学习交流群。程序员面试社区:236283328会分享一些资深架构师录制的视频录像:Spring、MyBatis、Netty源码分析、高并发、高性能、分布式、微服务架构原理、JVM性能优化、分布式架构等这些成为建筑师必备的知识体系。还可以领取免费的学习资源,目前受益良多的SQL优化神器:explainSQL优化的场景很多,网上也有很多技巧,根本想不起来!要想彻底解决这个问题,我觉得解决这个问题的唯一方法就是结合索引背后的数据结构和原理,在正确理解的情况下,遇到写SQL或者慢SQL查询的时候,我们才有分析的基础,然后用explain工具验证一下,应该问题不大。解释查询的结果可以告诉您正在使用哪些索引、表是如何扫描的,等等。这里我将演示一个Demo。数据表同学:注意复合索引(年龄,地址)符合最左前缀匹配复合索引失败OK,到这里,准备工作结束,查询容易,优化不易,且写且珍惜!
