Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2019
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.53 KB | None | 0 0
  1. 索引的本质:索引(Index)是帮助MySQL高效获取数据的数据结构
  2. 在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。
  3. 索引的存储分类
  4. MYSQL目前提供了一下4种索引。
  5. B-Tree 索引:最常见的索引类型,大部分引擎都支持B树索引。
  6. HASH 索引:只有Memory引擎支持,使用场景简单。
  7. R-Tree 索引(空间索引):空间索引是MyISAM的一种特殊索引类型,主要用于地理空间数据类型。
  8. Full-text (全文索引):全文索引也是MyISAM的一种特殊索引类型,主要用于全文索引,InnoDB从MYSQL5.6版本提供对全文索引的支持。
  9. Mysql目前不支持函数索引,但是能对列的前面某一部分进行索引,例如标题title字段,可以只取title的前10个字符进行索引,这个特性可以大大缩小索引文件的大小,
  10. 但前缀索引也有缺点,在排序Order By和分组Group By 操作的时候无法使用。
  11. 语法:create index index_title on film(title(10)) //取title的前10个字符进行索引
  12. B-TREE索引类型
  13. 1:普通索引
  14. 最基本的索引类型,而且它没有唯一性之类的限制。普通索引可以通过以下几种方式创建:
  15. (1)创建索引: CREATE INDEX 索引名 ON 表名(列名1,列名2,...);
  16. (2)修改表: ALTER TABLE 表名 UNIQUE索引
  17. 2:UNIQUE索引
  18. 表示唯一的,不允许重复的索引,如果该字段信息保证不会重复例如身份证号用作索引时,可设置为unique:
  19. (1)创建索引:CREATE UNIQUE INDEX 索引名 ON 表名(列的列表);
  20. (2)修改表:ALTER TABLE 表名ADD UNIQUE 索引名 (列的列表);
  21. (3)创建表时指定索引:CREATE TABLE 表名( [...], UNIQUE 索引名 (列的列表) );ADD INDEX 索引名 (列名1,列名2,...);
  22. (3)创建表时指定索引:CREATE TABLE 表名 ( [...], INDEX 索引名 (列名1,列名 2,...) );
  23. 3:主键:PRIMARY KEY索引
  24. 主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。
  25. 一 索引选择原则
  26. 1. 较频繁的作为查询条件的字段应该创建索引
  27. 2. 唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件
  28. 3. 更新非常频繁的字段不适合创建索引
  29. 4. 不会出现在 WHERE 子句中的字段不该创建索引
  30. 二 索引选择原则细述
  31. 1:性能优化过程中,选择在哪个列上创建索引是最非常重要的。可以考虑使用索引的主要有 两种类型的列:在where子句中出现的列,在join子句中出现的列,而不是在SELECT关键字后选择列表的列;
  32. 2:索引列的基数越大,索引的效果越好。例如,存放出生日期的列具有不同的值,很容易区分行,而用来记录性别的列,只有"M"和"F",则对此进行索引没有多大用处,因此不管搜索哪个值,都会得出大约一半的行
  33. 3:使用短索引,如果对字符串列进行索引,应该指定一个前缀长度,可节省大量索引空间,提升查询速度;
  34. 4:利用最左前缀
  35. 三 索引选择注意事项
  36. 1:索引虽然加快了查询速度,但索引也是有代价的:索引文件本身要消耗存储空间,同时索引会加重插入、删除和修改记录时的负担,另外,MySQL在运行时也要消耗资源维护索引,因此索引并不是越多越好。
  37. 2:索引的选择性较低。所谓索引的选择性(Selectivity),是指不重复的索引值(也叫基数,Cardinality)与表记录数(#T)的比值:
  38. Index Selectivity = Cardinality / #T
  39. 显然选择性的取值范围为(0, 1],选择性越高的索引价值越大,这是由B+Tree的性质决定的。
  40. 3:MySQL只对一下操作符才使用索引:<,<=,=,>,>=,between,in, 以及某些时候的like(不以通配符%或_开头的情形)。
  41. 4:在修改表的内容时,索引必须进行更新,有时可能需要重构,因此,索引越多,所花的时间越长。理论上每张表里面最多可创建16个索引
  42. 如果某列数据创建了索引,那么在更新该列数据时索引也会进行更新。
  43. 5:在表中已经存在大量数据的前提下,为某个字段段建立索引,建立速度会很慢
  44. 6:索引列不能参与计算,保持列“干净”
  45. 7:null列是可以用到索引的,不管是单列索引还是联合索引,但仅限于is null,is not null是不走索引的。
  46. 8:
  47.  
  48. 索引的最左匹配特性:当b+树的数据项是复合的数据结构,比如(name,age,sex)的时候,b+数是按照从左到右的顺序来建立搜索树的,比如当(张三,20,F)这样的数据来检索的时候,b+树会优先比较name来确定下一步的所搜方向,如果name相同再依次比较age和sex,最后得到检索的数据;但当(20,F)这样的没有name的数据来的时候,b+树就不知道下一步该查哪个节点,因为建立搜索树的时候name就是第一个比较因子,必须要先根据name来搜索才能知道下一步去哪里查询。比如当(张三,F)这样的数据来检索时,b+树可以用name来指定搜索方向,但下一个字段age的缺失,所以只能把名字等于张三的数据都找到,然后再匹配性别是F的数据了, 这个是非常重要的性质,即索引的最左匹配特性。
  49.  
  50. 聚集索引与辅助索引(非聚集索引)
  51. 聚集索引与辅助索引相同的是:不管是聚集索引还是辅助索引,其内部都是B+树的形式,即高度是平衡的,叶子结点存放着所有的数据。
  52. 聚集索引与辅助索引不同的是:叶子结点存放的是否是一整行的信息
  53. 聚簇索引保证关键字的值相近的元组存储的物理位置也相同,一个表只能有一个聚簇索引但可以有多个非聚集索引
  54. 聚集索引包含行记录的全部数据,对主键的排序查找和范围查找速度非常快,叶子节点的数据就是用户所要查询的数据。
  55. 非聚集索引叶子节点不包含行记录的全部数据,叶子节点除了包含键值以外,每个叶子节点中的索引行中还包含一个书签(bookmark)。该书签用来告诉InnoDB存储引擎去哪里可以找到与索引相对应的行数据。
  56.  
  57.  
  58. 辅助索引的存在并不影响数据在聚集索引中的组织,因此每张表上可以有多个辅助索引,但只能有一个聚集索引。当通过辅助索引来寻找数据时,InnoDB存储引擎会遍历辅助索引并通过叶子级别的指针获得只想主键索引的主键,然后再通过主键索引来找到一个完整的行记录。
  59. 举例来说,如果在一棵高度为3的辅助索引树种查找数据,那需要对这个辅助索引树遍历3次找到指定主键,如果聚集索引树的高度同样为3,那么还需要对聚集索引树进行3次查找,最终找到一个完整的行数据所在的页,因此一共需要6次逻辑IO访问才能得到最终的一个数据页。
  60. 通过辅助索引找到主键索引的主键-->从聚集索引查找该主键对应的行数据记录。 需要查找两颗索引数
  61.  
  62.  
  63. 在innodb中,表数据文件本身就是按照B+Tree(BTree即Balance True)组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。
  64. 这个索引的key是数据表的主键,因此innodb表数据文件本身就是主索引。
  65. 因为inndob的数据文件要按照主键聚集,所以innodb要求表必须要有主键(Myisam可以没有),
  66. 如果没有显式定义,则mysql系统会自动选择一个可以唯一标识数据记录的列作为主键,
  67. 如果不存在这种列,则mysql会自动为innodb表生成一个隐含字段作为主键,这字段的长度为6个字节,类型为长整型.
  68. InnoDB的辅助索引data域存储相应记录主键的值而不是地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。
  69.  
  70. MyISAM的索引文件仅仅保存数据记录的地址。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。MyISAM中索引检索的算法为首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,则取出其data域的值,然后以data域的值为地址,读取相应数据记录。
  71.  
  72.  
  73. MyISAM创建的非聚集索引与InnoDB创建的非聚集索引的区别是MyISAM创建的非聚集索引中B+Tree的节点保存的数据是对应的记录行的地址,而InnoDB创建的非聚集索引中B+树的节点保存的数据是主键值,然后根据主键值再到对应的聚集索引树上找到对应的记录。
  74.  
  75.  
  76. 注意:为区分度低的字段建立索引,索引树的高度会很高
  77. 尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0;
  78. 回忆b+树的结构,查询的速度与树的高度成反比,要想将树的高低控制的很低,需要保证:在某一层内数据项均是按照从左到右,从小到大的顺序依次排开,即左1<左2<左3<...
  79. 而对于区分度低的字段,无法找到大小关系,因为值都是相等的,毫无疑问,还想要用b+树存放这些等值的数据,只能增加树的高度,字段的区分度越低,则树的高度越高。极端的情况,索引字段的值都一样,那么b+树几乎成了一根棍
  80.  
  81.  
  82. 联合索引
  83. 从本质上来说,联合索引就是一棵B+树,不同的是联合索引的键值得数量不是1,而是>=2。
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement