当前位置: 首页 > 后端技术 > PHP

PHP面试MySQL数据库索引

时间:2023-03-30 05:09:36 PHP

大家好,我是PHP程序员面试笔试系列的作者刘毅。本周(2019.3.4至3.8)135篇更新文章如下:周一:PHP面试MySQL数据库基础知识周??三:PHP面试MySQL数据库索引周五:PHP面试MySQL数据库面试题《索引的优缺点有哪些》以及使用原则?”文章,关注公众号:“六一编程库”,回复:“索引”,我发给你。以下内容部分来自《PHP程序员面试笔试宝典》,如需转载请注明出处。1、什么是指数?索引是一种单独的物理存储结构,用于对数据库表中一个或多个列的值进行排序。它是表中一个或多个列中的值以及在表中物理标识这些值的相应数据的集合。指向页面的逻辑指针列表。索引的作用相当于书的目录,根据目录中的页码可以快速找到需要的内容。它基本上提供指向存储在表的指定列中的数据值的指针,然后根据指定的排序顺序对这些指针进行排序。数据库使用索引查找特定值,然后向上查找包含该值的行。这样可以更快的执行表对应的SQL语句,快速访问数据库表中的具体信息。索引的特点如下:①可以提高数据库的检索速度;②降低数据库插入、修改、删除等维护任务的速度;③可以直接或间接创建;④只能在表上创建,不能在视图上创建;⑤使用查询处理器执行SQL语句时,一张表一次只能使用一个索引;⑥索引可用于优化隐藏。索引的分类和使用如下:1.直接创建索引和间接创建索引直接创建索引:CREATEINDEXmycolumn_indexONmytable(myclumn)。间接创建索引:定义主键约束或唯一键约束,间接创建索引。2.普通索引和唯一索引普通索引:CREATEINDEXmycolumn_indexONmytable(myclumn)。唯一索引:确保索引列中的所有数据都是唯一的,可以用于聚簇索引和非聚簇索引。在mytable(mycolumn)3上创建唯一的COUSTERED索引myclumn_cindex。单一索引和复合索引单一索引:即非复合索引。复合索引:又称复合索引,索引创建语句中同时包含多个字段名,最多16个字段。CREATEINDEXname_indexONusername(firstname,lastname)4。聚簇索引与非聚簇索引(clusteredindex,聚簇索引)聚簇索引:物理索引,与基表物理顺序相同,数据值的顺序永远是有序的。CREATECLUSTEREDINDEXmycolumn_cindexONmytable(mycolumn)WITHALLOW_DUP_ROW(允许重复记录的聚集索引)非聚集索引:CREATEUNCLUSTEREDINDEXmycolumn_cindexONmytable(mycolumn)。2、索引的原理索引的目的是为了提高查询效率,这和我们查书的目录是一样的:先定位到章节,再定位到该章下的小节,再找到页数.类似的例子还有:查字典、查火车号、飞机班次等。其实质是:通过不断缩小你想要获取的数据范围,筛选出你想要的最终结果,同时转随机事件变成顺序事件。也就是说,有了这种索引机制,我们就可以一直使用同一种查找方式来锁定数据。数据库也是如此,但显然要复杂得多,因为它不仅面临等价查询,还有范围查询(>、<、between、in)、模糊查询(like)、联合查询(or)等等。数据库应该如何选择来处理所有的问题?让我们回忆一下字典的例子。能不能把数据切段,分段查询呢?最简单的如果有1000条数据,1到100分第一段,101到200分第二段,201到300分第三段……这样,要查第250个数据,只要找到第三段就可以了,一次性去掉90%的无效数据。但是如果是1000万条记录,多少段比较好呢?有一点算法基础的同学会想到搜索树,其平均复杂度为lgN,具有很好的查询性能。但是这里我们忽略了一个关键问题,复杂度模型是基于每次相同的操作成本来考虑的。数据库的实现比较复杂。一方面,数据存储在磁盘上。另一方面,为了提高性能,每次都可以将一部分数据读入内存进行计算,因为我们知道,访问磁盘的开销大约是访问内存的10万。次,所以简单的搜索树很难满足复杂的应用场景。整理了一篇《索引的优缺点和使用原则是什么?3、索引的数据结构任何数据结构都不是凭空产生的,它一定有它的背景和使用场景。现在总结一下我们需要这个数据结构来做什么,其实很简单,就是:每次查数据的时候,把磁盘IO的次数控制在一个很小的数量级,最好是恒定的数量级。那么我们想,可控性强的多路搜索树是否可以满足需求呢?这样,b+树就应运而生了。如上图所示,是一个b+树。b+树的定义请参考B+树。这里我们只谈几个重要的点。我们称浅蓝色块为磁盘块。您可以看到每个磁盘块都包含几个数据项。(以深蓝色显示)和指针(以黄色显示),如磁盘块1包含数据项17和35,包括指针P1、P2、P3,P1代表小于17的磁盘块,P2代表17到35之间的磁盘块,P3表示超过35个磁盘块。真正的数据存在于叶子节点中,即3、5、9、10、13、15、28、29、36、60、75、79、90、99。非叶子节点不存储真正的数据,而只存储引导搜索方向的数据项,如17、35等数据表中实际上并不存在。b+树的查找过程如图所示。如果要查找数据项29,那么首先从磁盘中加载磁盘块1到内存中。这时发生IO,在内存中使用二分查找,确定29在17和35之间,锁定磁盘块1的P2指针,内存时间可以忽略不计,因为很短(相比到磁盘IO),磁盘块3通过磁盘块1的P2指针的磁盘地址从磁盘加载到内存,发生第二次IO,29在26到30之间,锁定P2指针ofdiskblock3,通过指针加载diskblock8到内存,发生第三次IO,同时在内存中做二分查找找到29,结束查询,一共3次IO。真实情况是一棵3层的b+树可以表示百万条数据。如果百万级的数据查找只需要三个IO,那么性能的提升将是巨大的。如果没有索引,每个数据项需要一次IO,那么一共需要几百万次IO,显然成本非常非常高。b+树的特性1.索引字段要尽可能小:通过上面的分析我们知道,IO的个数取决于b+数的高度h。假设当前数据表中的数据为N,每个磁盘块中的数据项数为m。则有h=㏒(m+1)N,当数据量N一定时,m越大,h越小;而m=磁盘块的大小/数据项的大小,一个磁盘块的大小也是一个数据页的大小是固定的。数据项占用的空间越小,数据项的个数越多,树的高度就越低。这就是为什么每个数据项,也就是索引字段,要尽可能的小。比如int占用4个字节,比bigint8个字节少了一半。这就是为什么b+树要求真正的数据放在叶子节点而不是内部节点。一旦放入内部节点,磁盘块的数据项将显着下降,导致树高增加。当数据项等于1时,会退化为线性表。2、索引的最左匹配特征(即从左到右匹配):当b+树的数据项为复合数据结构时,如(name,age,sex),b+数依次为从左到右构建一个搜索树,比如当检索到(张三,20,F)这样的数据时,b+树会先比较名字来决定下一个搜索方向。如果姓名相同,则依次比较年龄和性别,最后得到检索到的数据;但是当(20,F)这样没有name的数据来的时候,b+树不知道接下来要查哪个节点,因为name是建搜索树时第一个比较的因素,所以必须先根据name进行Search才能知道下一步在哪里查询。比如检索(张三,F)这样的数据时,b+树可以使用name来指定查找方向,但是缺少了下一个字段age,所以我们只能找到name等于张三的所有数据,然后匹配性别就是F的数据,这是一个很重要的属性,就是索引的最左匹配特征。通知:本周五(3.8)将更新PHP面试MySQL数据库的面试题,敬请期待。以上内容节选自《PHP程序员面试笔试宝典》书籍。目前,本书没有电子版。各大电商平台均可购买纸质版。更多PHP相关面试知识和考题,请关注公众号获取:六一编程库,对本文有任何问题或建议可以留言。我会不断改进,追求极致,谢谢大家的支持。