zoukankan      html  css  js  c++  java
  • mysql索引详细学习笔记

    参考:http://m.blog.csdn.net/kennyrose/article/details/7532032

       http://www.cnblogs.com/ggjucheng/archive/2012/11/04/2754128.html

       http://m.blog.csdn.net/hguisu/article/details/7786014

       http://www.cnblogs.com/AK2012/archive/2013/01/04/2844283.html

    一、索引的定义:

      索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合  要求的记录。表里面的记录数量越多,这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置。如果表有   1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍。

    二、疑问:遍历数据库表检索需要时间,查找索引也需要时间,为什么索引可以加快检索速度?  索引存储结构是B树,因为B树是有序的,所以查找的速度会更快。

      在B- 树中进行查找包含两种基本操作:

            ( 1) 在B- 树中查找结点;

            ( 2) 在结点中查找关键字。

           由于B- 树通常存储在磁盘上, 则前一查找操作是在磁盘上进行的, 而后一查找操作是在内存中进行的, 即在磁盘上找到指针p 所指结点后, 先将结点中的信息读入内存, 然后再利用顺序查找或折半查找查询等于K 的关键字。显然, 在磁盘上进行一次查找比在内存中进行一次查找的时间消耗多得多.  因此, 在磁盘上进行查找的次数、即待查找关键字所在结点在B- 树上的层次树, 是决定B树查找效率的首要因素。

      例子:

        

        上图展示了一种可能的索引方式。左边是数据表,一共有两列七条记录,最左边的是数据记录的物理地址(注意逻辑上相邻的记录在磁盘上也并不是一定物理相邻的)。为了加快    Col2的查找,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个指向对应数据记录物理地址的指针,这样就可以运用二叉查找在O(log2n)的复杂度内获取到    相应数据。

    三、使用索引的优点与缺点

      优点:

      创建索引可以大大提高系统的性能。

      第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。

      第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。

      第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。

      第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。

      第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。

      缺点: 

      第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。

      第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。

      第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。四、什么情况下适合使用索引 

      建立索引的原则:

      1) 定义主键的数据列一定要建立索引。

      2) 定义有外键的数据列一定要建立索引。

      3) 对于经常查询的数据列最好建立索引。

      4) 对于需要在指定范围内的快速或频繁查询的数据列;

      5) 经常用在WHERE子句中的数据列。

      6) 经常出现在关键字order by、group by、distinct后面的字段,建立索引。如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致,否则索引不会被使用。

      7) 对于那些查询中很少涉及的列,重复值比较多的列不要建立索引。

      8) 对于定义为textimagebit的数据类型的列不要建立索引。

      9) 对于经常存取的列避免建立索引

      9) 限制表上的索引数目。对一个存在大量更新操作的表,所建索引的数目一般不要超过3个,最多不要超过5个。索引虽说提高了访问速度,但太多索引会影响数据的更新操作。

      10) 对复合索引,按照字段在查询条件中出现的频度建立索引。在复合索引中,记录首先按照第一个字段排序。对于在第一个字段上取值相同的记录,系统再按照第二个字段的取值排  序,以此类推。因此只有复合索引的第一个字段出现在查询条件中,该索引才可能被使用,因此将应用频度高的字段,放置在复合索引的前面,会使系统最大可能地使用此索引,发挥  索引的作用。

    五、分析索引效率

    现在我们已经知道了一些如何选择索引列的知识,但还无法判断哪一个最有效。MySQL提供了一个内建的SQL命令帮助我们完成这个任务,这就是EXPLAIN命令。EXPLAIN命令的一般语法是:EXPLAIN 。你可以在MySQL文档找到有关该命令的更多说明。下面是一个例子: 

    EXPLAIN SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan' AND age='17'; 

    这个命令将返回下面这种分析结果:
    下面我们就来看看这个EXPLAIN分析结果的含义。 

    table:这是表的名字。 
    type:连接操作的类型。下面是MySQL文档关于ref连接类型的说明:
      “对于每一种与另一个表中记录的组合,MySQL将从当前的表读取所有带有匹配索引值的记录。如果连接操作只使用键的最左前缀,或者如果键不是UNIQUE或PRIMARY KEY类型  (换句话说,如果连接操作不能根据键值选择出唯一行),则MySQL使用ref连接类型。如果连接操作所用的键只匹配少量的记录,则ref是一种好的连接类型。”
      在本例中,由于索引不是UNIQUE类型,ref是我们能够得到的最好连接类型。
      如果EXPLAIN显示连接类型是“ALL”,而且你并不想从表里面选择出大多数记录,那么MySQL的操作效率将非常低,因为它要扫描整个表。你可以加入更多的索引来解决这个问题。预  知更多信息,请参见MySQL的手册说明。
    possible_keys: 
      可能可以利用的索引的名字。这里的索引名字是创建索引时指定的索引昵称;如果索引没有昵称,则默认显示的是索引中第一个列的名字(在本例中,它是“firstname”)。默认索引名  字的含义往往不是很明显。
    Key: 它显示了MySQL实际使用的索引的名字。如果它为空(或NULL),则MySQL不使用索引。
    key_len: 
      索引中被使用部分的长度,以字节计。在本例中,key_len是102,其中firstname占50字节,lastname占50字节,age占2字节。如果MySQL只使用索引中的firstname部分,则key_len  将是50。
    ref: 它显示的是列的名字(或单词“const”),MySQL将根据这些列来选择行。在本例中,MySQL根据三个常量选择行。
    rows: MySQL所认为的它在找到正确的结果之前必须扫描的记录数。显然,这里最理想的数字就是1。
    Extra: 这里可能出现许多不同的选项,其中大多数将对查询产生负面影响。在本例中,MySQL只是提醒我们它将用WHERE子句限制搜索结果集。

      

  • 相关阅读:
    论文笔记系列-DARTS: Differentiable Architecture Search
    Win10安装TensorFlow1.9-GPU版本
    论文笔记系列-Efficient Neural Architecture Search via Parameter Sharing
    论文笔记模板
    无偏估计
    【TensorFlow】tf.nn.softmax_cross_entropy_with_logits的用法
    Python学习札记(十三) Function3 函数参数二
    LeetCode Add Two Numbers
    Python学习札记(十二) Function3 函数参数一
    Python学习札记(十一) Function2 函数定义
  • 原文地址:https://www.cnblogs.com/Zchaowu/p/7483237.html
Copyright © 2011-2022 走看看