之前有一个面试,MySQL索引的原理和使用完全被面试官看懵了。我下定决心总结一下,但是我没有时间(其实我很懒。。。),你准备好了吗?什么是索引?数据库索引是数据库管理系统(DBMS)中的一种排序数据结构,它可以对数据库表中一个或多个列的值进行排序,以协助更快地访问数据库表中的特定数据。通俗地说,我们可以把数据库索引比作一本书前面的目录,可以加快数据库的查询速度。为什么需要索引?思考:如何在图书馆找到一本书?试想一下,如果图书馆里没有其他辅助手段,你只能一本一本地走到黑暗中,一本又一本地找。经过3个小时的不断寻找,你终于找到了你要看的书,但此时天已经黑了。为了避免这样的事情发生,每个图书馆都配备了图书馆管理系统。想要找一本书,首先要在系统上找到这本书所在的门牌号,书架号,书架号。那个方向,然后就可以大摇大摆的直接去取书了,很快就可以找到我们需要的书了。索引就是这个原理,它可以帮助我们快速检索数据。一般的应用系统在对数据库的操作中,遇到最多也最容易出现问题的就是一些复杂的查询操作。当数据库中的数据量很大时,查找数据会变得很慢,这将极大地影响整个应用系统的性能。效率,我们可以使用索引来提高数据库的查询效率。B-Tree和B+Tree目前,大多数数据库系统和文件系统都使用B-Tree或者它的变体B+Tree作为索引结构,这里就讲一下。推荐阅读:为什么建立索引可以提高查询速度?B-Tree就是B树,注意(不是B减树),B树是多路搜索树。使用B-Tree结构可以显着减少定位记录的中间过程,从而加快访问速度。B-Tree具有以下特点:定义任何非叶子节点至多有M个子节点,且M>2。根节点的子节点数为[2,M]。除根节点外的非叶节点的儿子数为[M/2,M],四舍五入。每个节点至少存储M/2-1(向上取整),至多M-1个关键字;(至少2个关键字)。非叶子节点的关键字个数=儿子指针的个数-1。非叶子节点的关键字:K[1],K[2],...,K[M-1],K[i]<=K[i+1]。指向非叶子节点的指针:P[1],P[2],...,P[M](其中P[1]指向key小于K[1]的子树,P[M]指向一棵key大于K的子树[M-1],其他P[i]指向key属于(K[i-1],K[i]))的子树。所有叶节点都处于同一级别。b树的一些特点:关键词的集合分布在整棵树的所有节点中;任一关键字出现且仅出现在一个节点中;搜索可能在非叶节点处结束;它的搜索性能等。值得在关键字语料库中进行二分查找。B树查找:从根节点开始,对该节点中的关键字(有序)序列进行二分查找,如果命中则结束,否则进入查询关键字范围的子节点;重复这个操作,直到对应的节点指针为空,或者已经是叶节点。比如下面的B-tree中,查找第43个元素的过程是这样的:根据根节点指针找到18和37所在的节点,将这个节点读入内存,进行第一次磁盘IO。这时发现43>37,找到指针p3。根据指针p3,找到42和51所在的节点,将这个节点读入内存,进行第二次磁盘IO。这时发现42<43<51,找到了指针p2。根据指针p2,找到43和46所在的节点,将这个节点读入内存,进行第三次磁盘IO。这个时候我们已经找到了43这个元素,这个过程中一共进行了3次磁盘IO。B+TreeB+Tree是B-Tree的变种。B+Tree与B-Tree相比有以下区别:一个有n个子树的非叶子节点包含n个关键字(B-tree为n-1),即非叶子节点的子树指针相同as关键字的个数是一样的。这些关键字不存储数据,仅用于索引,所有数据都存储在叶节点中(B-tree为每个关键字存储数据)。2.所有的叶子节点包含了所有关键词的信息和包含这些关键词的记录的指针,叶子节点本身按照关键词大小从小到大的顺序链接在一起。3、所有的非叶子节点都可以看作是叶子节点的索引部分。4、同一个数会在不同节点重复出现,根节点的最大元素就是b+树的最大元素。与B树相比,B+树作为索引的优势在于B+树的磁盘IO成本更低:B+树的非叶子节点没有指向数据行的指针,因此索引的数量同一磁盘容量存储的节点越多,相应的IO读写次数一定会减少。B+树的查询效率更稳定:因为所有的数据都存储在叶子节点中。所有关键字查询的路径长度相同,每条数据的查询效率是等价的。所有叶子节点组成一个有序链表,更容易找到。MySQL常用的两种存储引擎MyISAM和InnoDB的索引,都是使用B+树作为数据结构,但又有所不同(这里只说两种索引的区别)。推荐阅读:InnoDB的B+树可以存储多少行数据?MyISAM索引和Innodb索引的区别MyISAM使用B+树作为索引结构。叶子节点的数据字段保存了存储数据的地址。主键索引键值唯一,辅助索引键可以重复。两者在结构上是一样的。关注微信公众号:Java技术栈,后台回复:mysql,可以领取我整理的N篇MySQL教程,都是干货。所以MyISAM中的索引检索算法是先按照B+Tree的查找算法来查找索引。如果要查找的key存在,则取出数据域的值,然后以数据域的值作为地址,读取对应的数据记录。因此,索引文件和数据文件是分开的,从索引中获取数据的地址,而不是数据。Innodb同样采用B+树作为索引结构,但具体实现方式与MyISAM完全不同。首先,数据表本身是按照B+树组织的,所以数据文件本身就是主键索引文件。叶子节点的键值是数据表的主键,数据字段是完整的数据记录。因此,InnoDB表数据文件本身就是主键索引(这就是为什么MyISAM可以允许没有主键,而Innodb必须有主键的原因)。与MyISAM索引的第二个区别是InnoDB的辅助索引的data字段存储的是对应数据记录的主键值,而不是地址。换句话说,InnoDB的所有二级索引都将主键作为数据字段。IndexTypeOrdinaryIndex:(由关键字KEY或INDEX定义的索引)其唯一任务是加速对数据的访问。唯一索引:普通索引允许被索引的数据列包含重复值,而唯一索引则不允许,但可以为空。所以任务就是保证访问速度,避免数据重复。主键索引:在主键字段上创建的索引,一张表只有一个主键索引。复合索引:多个列值组成一个索引,专门用于复合搜索。全文索引:对文本内容进行切分和搜索。(MyISAM和InnoDB存储引擎在MySQL5.6及以后版本支持全文索引。)推荐阅读:MySQL索引B+树原理,以及索引构建的几种原理。索引使用策略及优缺点使用索引主键自动创建唯一索引。经常出现在WHERE或ORDERBY语句中作为查询条件的列应该被索引。查询中与其他表关联的字段,外键关系被索引。经常用于聚合函数的列应该被索引,例如min()和max()等聚合函数。不要在不使用索引的情况下为频繁增删改查的列创建索引。不为具有大量重复项的列编制索引。如果表记录太少,不要创建索引,因为数据少,查询所有数据可能比遍历索引花费的时间更少,索引可能不会产生优化效果。最左匹配原则创建联合索引时,默认会从最左开始,所以索引列的顺序很重要。建立索引时,最常用的应该放在左边。使用select时也是如此,从最左边开始依次匹配右边的。优点是可以保证数据库表中每一行数据的唯一性。可以大大加快数据的索引速度。加速表到表的连接。它可以显着减少查询中分组和排序的时间。缺点创建和维护索引需要时间,而且这个时间随着数据量的增加而增加。索引需要占用物理空间。除了数据表占用的数据空间外,每个索引还占用一定的物理空间。如果需要建立聚簇索引,需要的空间会更大。其实索引就是用空间换取时间。.当对表中的数据进行增删改查时,索引也必须动态维护,降低了维护效率。验证索引是否可以提高查询性能创建测试表index_test使用python脚本程序通过pymsql模块向表中添加10万条数据importpymysqldefmain():#CreateaConnectionconnectconn=pymysql.connect(host='localhost',port=3306,database='db_test',user='root',password='deepin',charset='utf8')#获取游标对象cursor=conn.cursor()#插入10万次数据foriinrange(100000):cursor.execute("insertintoindex_testvalues('haha-%d')"%i)#提交数据conn.commit()if__name__=="__main__":main()在mysql终端开启运行时间监控:setprofiling=1;搜索第10,000条数据ha-99999select*fromindex_testwherename='haha-99999';查看执行时间:showprofiles;为表index_test的name列创建索引:createindexnameindexonindex_test(name(10));再次执行查询语句,查看执行时间:可以看到合适的索引确实可以显着提高某些字段的查询效率。最后,感谢女友在生活和工作中对我的包容、理解和支持!
