zoukankan      html  css  js  c++  java
  • 【Mysql】索引

      索引在mysql中的作用主要是在海量数据中快速查找到指定的数据。在设计数据表格的时候应该对列添加索引也是一个重要的问题,因为这决定了在查找数据时查找速度,当然数据很大时,设计不好的索引不仅不能加速查找,反而会变得更加慢。因此设计一个好的索引是非常重要的一个问题,但是怎么的索引的才是一个好索引?这就需要我们对索引有深入了解。基于此我打算从以几个方面进行总结:(1)索引的类型、(2)高性能索引策略、(3)案例学习。 

    一、索引类型


      索引的类型有很多种,因为它是在存储引擎层实现的,所以并没有一个统一的标准。我主要梳理以下被两个经常使用的索引类型:B+Tree索引、Hash索引。

    (1)、B+树索引


      B+树索引是使用最广泛的索引类型(由B树衍生而来),如其名我们可以知道索引使用的底层数据结构是B+树,B+树的存储特点如下图:

      从图中我们可以看到在B+树的内部节点上不包含数据信息,叶子结点都是以链表相链的。具体有关B树和B+树的性质可以参考阅读 https://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html

      B+树之所以能够加快数据的访问速度,是因为存储引擎不再需要进行全表扫描来获取需要的数据,取而代之的是从索引根节点(顶部节点)开始搜索。存储引擎根据根节点的指针向下层查找,通过比较查找的值和当前节点的值来决定找到合适的指针指向下一层子节点。最终达到叶子节点,根据当前值判断要么找到对应的值,要么记录不存在。

      优点在数据存储时,在叶子节点存储是按照顺序进行存储,所以在我们使用order by 和 group by 时运行速度会非常快。可以大大的减小服务器需要扫描表的数据量、避免排序和临时表、将随机I/O转化为顺序I/O。

      缺点:

    (2)、Hash索引


      哈希索引基于哈希表实现,只有精确匹配索引所有列的查询才有效。对于每一行数据,存储引擎都会对所有的索引计算出一个哈希码,不同的数据对应不同的哈希码。哈希索引将哈希码存储在索引中,同时在哈希码表中保存数据指针指向数据的位置。对于hash索引中当存储海量数据时,会存在hash冲突的问题。解决冲突的办法是链表法。如下图所示:

      优点:hash索引在进行等值查找时可以在O(1)的时间内查找到数据,因此查找效率非常高。

      缺点:Hash索引并不是按照索引值的顺序存储的,因此它并不适合排序(会进行全表扫表对其进行排序,效率较低)、只支持等值查询,不支持范围查询、当Hash冲突很多时,即便是等值查找效率也会很低,另外维护代价也会变高。

    二、高性能索引策略


      正确的创建和使用索引是实现高性能查询的基础。在第一部分介绍了两种常用的索引的底层数据结构以及其优缺点。这一部分我们来阐述索引使用策略。

    (1)、独立的列


      在使用包含索引的列进行查询时,必须保证索引列不是表达式的一部分或者不能是函数的参数。例如下面的两个查询不能使用索引(假设id字段添加了索引):

    1 select id from table where id +1 = 5;            where字段中实际上id= 5,但是mysql无法自动解析这个方程式,因此不会使用索引策略。(表达式)
    2 
    3 select * from table  where to_days(current_date) - to_days(date_col) <= 10;      在这个sql中列的数据是函数的参数,mysql同样不会进行自动解析。

    (2) 、多列索引


       有时候在表中会存在多个单独索引,例如在创建表的时候这样创建:

    create table t (
    c1 int, 
    c2 int,  
    c3 int, 
    key(c1), 
    key(c2), 
    key(c3));
    

       在这个表中,为每一列都创建了一个单独索引。这种建立索引的方式大部分情况下并不能提高mysql的查询性能。假设我们需要执行下列的查询:

     1 select c1, c2 from t where c1 = 1 or c2 = 1;
    

       在上面这个查询中,如果在较老的mysql版本中只能使用其中一个单列索引,然后这种情况下没有哪一个独立的单列索引是非常有效的,因此它会执行全表扫描。在mysql 5.0版本之后,引入了一种叫“索引合并”的策略。一定程度上可以使用表上的多个单列索引来定位指定的行。具体是mysql会将where后面中的两个条件分别使用各自的索引查询结果,然后将结果进行合并(当然 and同理)。

      注意:虽然多列索引可以使用索引合并这种策略进行优化, 但是更多的时候这意味着表上的索引策略建立的很糟糕。比如,当涉及到需要多个索引进行相交操作时,更多的时候我们需要的时联合索引,而不是这样的单列索引。另外,索引优化策略在每个结果集有大量的数据时,会耗费大量时间和计算能力来对多个结果集进行排序筛选等。性能下降的很快。

    (3)、选择合适的索引顺序


      

  • 相关阅读:
    前端下拉框
    使用Redis的有序集合实现排行榜功能
    python--list,str,dict,json,tuple互换用法实例
    微信支付
    C++创建及访问动态对象
    C++动态持久内存分配(new)
    C++函数与指针
    C++数组与指针
    C++指针基础
    MySQL再安装
  • 原文地址:https://www.cnblogs.com/GoodRnne/p/10979829.html
Copyright © 2011-2022 走看看