做电影网站教程,网站设计与制作教程1,游戏代理怎么做,dw网页制作教程 div视频教程在MySQL中#xff0c;主要有四种类型的索引#xff0c;分别为#xff1a;B-Tree索引#xff0c;Hash索引#xff0c;Fulltext索引(MyISAM 表)和R-Tree索引#xff0c;本文讲的是B-Tree索引。一、Mysql索引主要有两种结构#xff1a;BTree索引和Hash索引(a) Innodb存储引…在MySQL中主要有四种类型的索引分别为B-Tree索引Hash索引Fulltext索引(MyISAM 表)和R-Tree索引本文讲的是B-Tree索引。一、Mysql索引主要有两种结构BTree索引和Hash索引(a) Innodb存储引擎 默认是 BTree索引(b) MyISAM 存储引擎 默认是Fulltext索引(c)Memory 存储引擎 默认 Hash索引Hash索引mysql中只有Memory(Memory表只存在内存中断电会消失适用于临时表)存储引擎显示支持Hash索引是Memory表的默认索引类型尽管Memory表也可以使用BTree索引。Hash索引把数据以hash形式组织起来因此当查找某一条记录的时候速度非常快。但是因为hash结构每个键只对应一个值而且是散列的方式分布。所以它并不支持范围查找和排序等功能。BTree索引BTree是mysql使用最频繁的一个索引数据结构是Innodb和Myisam存储引擎模式的索引类型。相对Hash索引BTree在查找单条记录的速度比不上Hash索引但是因为更适合排序等操作所以它更受欢迎。毕竟不可能只对数据库进行单条记录的操作。带顺序访问指针的BTreeBTree所有索引数据都在叶子节点上并且增加了顺序访问指针每个叶子节点都有指向相邻叶子节点的指针。这样做是为了提高区间效率例如查询key为从18到49的所有数据记录当找到18后只要顺着节点和指针顺序遍历就可以以此向访问到所有数据节点极大提高了区间查询效率。大大减少磁盘I/O读取数据库系统的设计者巧妙利用了磁盘预读原理将一个节点的大小设为等于一个页这样每个节点需要一次I/O就可以完全载入。什么是索引索引(Index)是帮助数据库高效获取数据的数据结构。索引是在基于数据库表创建的它包含一个表中某些列的值以及记录对应的地址并且把这些值存储在一个数据结构中。最常见的就是使用哈希表、B树作为索引。一般的应用系统读写比例在10:1左右而且插入操作和一般的更新操作很少出现性能问题在生产环境中我们遇到最多的也是最容易出问题的还是一些复杂的查询操作因此对查询语句的优化显然是重中之重。说起加速查询就不得不提到索引了。为什么要使用索引我们知道数据库查询是数据库最主要的功能之一。而查询速度当然是越快越好。而当数据量越来越大的时候查询花费的时间会随之增长。而索引可以加速数据的查询。因为索引是有序排列的。举个例子来说假设我们有一个数据库表Employee这个表分别有三个字段nameageaddress。假设表中有1000条记录。假如没有使用索引当我们查询名为“Jesus”的雇员的时候即调用select name,age,address from Employee where name Jesus;此时数据库不得不在Employee表中对这1000条记录一条一条的进行判断name字段是否为“Jesus”。这也就是所谓的全表扫描。而当我们在Employee表上的name字段上创建索引时当我们查询名为“Jesus”的雇员时会通过索引查找去查询名为“Jesus”的雇员因为该索引已经按照字母顺序排列因此要查找名为“Jesus”的记录时会快很多因为名字首字母为“J”的雇员都是排列在一起的。通过该索引能获取到表中对应的记录。二叉查找树二叉查找树也称为有序二叉查找树满足二叉查找树的一般性质是指一棵空树具有如下性质1、任意节点左子树不为空,则左子树的值均小于根节点的值2、任意节点右子树不为空,则右子树的值均大于于根节点的值3、任意节点的左右子树也分别是二叉查找树4、没有键值相等的节点平衡二叉树树形结构是计算机系统里最重要的数据结构。我们知道二叉树的查找的时间复杂度是O(log2N)其查找效率与深度有关而普通的二叉树可能由于内部节点排列问题退化成链表这样查找效率就会很低。因此平衡二叉树是更好的选择因为它保持平衡即通过旋转调整结构保持最小的深度。其查找的时间复杂度也是O(log2N)。但实际上数据库中索引的结构也并非AVL树或更优秀的红黑树尽管它的查询的时间复杂度很低。为什么平衡二叉树也不适合作为索引之前说了平衡树的查找时间复杂度是O(log2N)已经很不错了但还是不适合作为索引结构。那么肯定是有一种更适合作为索引的数据结构。那么这个更适合作为索引的数据结构难道是查找的时间复杂度更低吗并不是。这种作为索引的数据结构的查找的时间复杂度也近似O(log2N)。那为什么平衡二叉树不适合作为索引呢索引是存在于索引文件中是存在于磁盘中的。因为索引通常是很大的因此无法一次将全部索引加载到内存当中因此每次只能从磁盘中读取一个磁盘页的数据到内存中。而这个磁盘的读取的速度较内存中的读取速度而言是差了好几个级别。注意我们说的平衡二叉树结构指的是逻辑结构上的平衡二叉树其物理实现是数组。然后由于在逻辑结构上相近的节点在物理结构上可能会差很远。因此每次读取的磁盘页的数据中有许多是用不上的。因此查找过程中要进行许多次的磁盘读取操作。而适合作为索引的结构应该是尽可能少的执行磁盘IO操作因为执行磁盘IO操作非常的耗时。因此平衡二叉树并不适合作为索引结构。B树的性质1、定义任意非叶子结点最多只有M个儿子且M22、根结点的儿子数为[2, M]3、除根结点以外的非叶子结点的儿子数为[M/2, M]4、每个结点存放至少M/2-1(取上整)和至多M-1个关键字(至少2个关键字)5、非叶子结点的关键字个数指向儿子的指针个数-16、非叶子结点的关键字K[1], K[2], …, K[M-1]且K[i] K[i1]7、非叶子结点的指针P[1], P[2], …, P[M]其中P[1]指向关键字小于K[1]的子树P[M]指向关键字大于K[M-1]的子树其它P[i]指向关键字属于(K[i-1], K[i])的子树8、所有叶子结点位于同一层B树比B树更适合作为索引的结构是B树。MySQL中也是使用B树作为索引。它是B树的变种因此是基于B树来改进的。为什么B树会比B树更加优秀呢B树有序数组平衡多叉树B树有序数组链表平衡多叉树B树的关键字全部存放在叶子节点中非叶子节点用来做索引而叶子节点中有一个指针指向一下个叶子节点。做这个优化的目的是为了提高区间访问的性能。而正是这个特性决定了B树更适合用来存储外部数据。MYSQL为什么采用B树而不是B树1、 B树的磁盘读写代价更低B树的内部节点并没有指向关键字具体信息的指针因此其内部节点相对B树更小如果把所有同一内部节点的关键字存放在同一盘块中那么盘块所能容纳的关键字数量也越多一次性读入内存的需要查找的关键字也就越多相对IO读写次数就降低了。2、B树的查询效率更加稳定由于非终结点并不是最终指向文件内容的结点而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同导致每一个数据的查询效率相当。3、由于B树的数据都存储在叶子结点中分支结点均为索引方便扫库只需要扫一遍叶子结点即可但是B树因为其分支结点同样存储着数据我们要找到具体的数据需要进行一次中序遍历按序来扫所以B树更加适合在区间查询的情况所以通常B树用于数据库索引。数据库索引采用B树的主要原因是B树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。正是为了解决这个问题B树应运而生。B树只要遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的而B树不支持这样的操作(或者说效率太低)。正如上面所说在数据库中基于范围的查询是非常频繁的因此MySQL最终选择的索引结构是B树而不是B树。b树性质1.索引字段要尽量的小通过上面的分析我们知道IO次数取决于b数的高度h假设当前数据表的数据为N每个磁盘块的数据项的数量是m则有h㏒(m1)N当数据量N一定的情况下m越大h越小而m 磁盘块的大小 / 数据项的大小磁盘块的大小也就是一个数据页的大小是固定的如果数据项占的空间越小数据项的数量越多树的高度越低。这就是为什么每个数据项即索引字段要尽量的小比如int占4字节要比bigint8字节少一半。这也是为什么b树要求把真实的数据放到叶子节点而不是内层节点一旦放到内层节点磁盘块的数据项会大幅度下降导致树增高。当数据项等于1时将会退化成线性表。2.索引的最左匹配特性(即从左往右匹配)当b树的数据项是复合的数据结构比如(name,age,sex)的时候b数是按照从左到右的顺序来建立搜索树的比如当(张三,20,F)这样的数据来检索的时候b树会优先比较name来确定下一步的所搜方向如果name相同再依次比较age和sex最后得到检索的数据但当(20,F)这样的没有name的数据来的时候b树就不知道下一步该查哪个节点因为建立搜索树的时候name就是第一个比较因子必须要先根据name来搜索才能知道下一步去哪里查询。比如当(张三,F)这样的数据来检索时b树可以用name来指定搜索方向但下一个字段age的缺失所以只能把名字等于张三的数据都找到然后再匹配性别是F的数据了 这个是非常重要的性质即索引的最左匹配特性。这也是经常考察的比如 我定义了 A,B,C的联合索引如果 我只传递了 A,B 能走索引吗答案是能因为最左侧原理索引使用注意事项1不要滥用索引①索引提高查询速度却会降低更新表的速度因为更新表时mysql不仅要更新数据保存数据还要更新索引保存索引②索引会占用磁盘空间2索引不会包含含有NULL值的列复合索引只要有一列含有NULL值,那么这一列对于此符合索引就是无效的因此我们在设计数据库设计时不要让字段的默认值为NULL。3MySQL查询只是用一个索引如果where字句中使用了索引的话那么order by中的列是不会使用索引的4likelike %aaa%不会使用索引而like aaa%可以使用索引二、选择索引的数据类型Mysql支持很多数据类型选择合适的数据类型存储数据对性能有很大的影响。(1)越小的数据类型通常更好越小的数据类型通常在磁盘、内存和cpu缓存中都需要更少的空间处理起来更快。(2)简单的数据类型更好整形数据比起字符处理开销更小因为字符串的比较更复杂。在MySQL中应用内置的日期和时间数据类型而不是字符串来存储时间以及用整形数据存储IP地址。(3)尽量避免NULL应该制定列为NOT NULL除非你想存储NULL。在MySQL中含有空值的列很难进行查询优化因为他们使得索引、索引的统计信息以及比较运算更加复杂。三、MySQL常见索引有主键索引、唯一索引、普通索引、全文索引、组合索引1INDEX(普通索引)ALTER TABLE table_name ADD INDEX index_name(col)最基本的索引没有任何限制2UNIQUE(唯一索引)ALTER TABLE table_name ADD UNIQUE(col)与“普通索引”类似不同的就是索引列的值必须唯一但允许有空值。3PRIMARY KEY(主键索引)ALTER TABLE table_name ADD PRIMARY KEY(col)是一种特殊的唯一索引不允许有空值。4FULLTEXT(全文索引)ALTER TABLE table_name ADD FULLTEXT(col)仅可用于MyISAM和InoDB针对较大的数据生成全文索引很耗时耗空间组合索引ALTER TABLE table_name ADD INDEX index_name(col1,col2,col3)为了更多的提高mysql效率可建立组合索引遵循“最左前缀”原则。创建复合索引应该将最常用(频率)做限制条件的列放在最左边一次递减。组合索引最左字段用in是可以用到索引的。相当于建立了col1,col1col2,col1col2col3三个索引聚集索引和辅助索引数据库中的BTree索引可以分为聚集索引(clustered index)和辅助索引(secondary index)。上面的BTree示例图在数据库中的实现即为聚集索引聚集索引的BTree中的叶子节点存放的是整张表的行记录数据。辅助索引与聚集索引的区别在于辅助索引的叶子节点并不包含行记录的全部数据而是存储相应行数据的聚集索引键即主键。当通过辅助索引来查询数据时InnoDB存储引擎会遍历辅助索引找到主键然后再通过主键在聚集索引中找到完整的行记录数据数据库适合创建索引的规则如下表的主键外键应该创建索引数据量比较大的表应该创建索引经常需要和其他表建立连接在连接字段应该创建索引经常出现在where子句中的字段应该创建索引。数据库不适合创建索引的情况比较大的文本字段或者长度较长的字段不适合创建索引频繁进行数据操作的表不适合创建过多的索引因为额外维护索引表需要更多的开销小型表(数据量低于300行)不要建立索引。参考链接