Mysql索引机制B+Tree

  1、问题引入
  
  有一个用户表,为了查询的效率,需要基于id去构建索引。构建索引我们需要考虑两个方面的问题,1个是查询的效率,1个是索引数据的存储问题。该表的记录需要支持百万、千万、甚至上亿的数据量,如果将索引存储到内存中,尽管内存的访问速度非常快,查询效率非常高,但是,占用内存会非常大。
  
  而且每次数据库重启后,索引数据就会丢失,需要在内存里重新构建索引。将索引存储到硬盘中,减少了内存的消耗,数据库重启,数据也不会丢失。
  
  确定了硬盘存储索引数据,接下来就需要选择合适的数据结构存储索引数据。首先我们会想到散列表,散列表查询性能很好,时间复杂度为O(1),但是如果想要快速查询id 在1~3之间的数据,散列表就不能满足了。散列表不满足要求,我们自然会想到另一种数据结构树,树的种类有很多种,到底哪种树适合基于磁盘构建索引呢?mysql采用b-tree的增强版b+tree 这种树去构建索引,这种树可以大大减少磁盘io的操作,提高查询效率。
  
  2、磁盘读写原理
  
  B-Tree是为磁盘等外存储设备设计的一种平衡查找树。因此在讲B-Tree之前先了解下磁盘的相关知识。
  
  2.1 硬盘组成:盘片(platter)、磁头(head)、磁道(track)、扇区(sector)、柱面(cylinder)。
  
  硬盘中一般会有多个盘片(platter)组成,每个盘片包含两个面,每个盘面都对应地有一个读/写磁头。每个盘面都被划分为数目相等的磁道,并从外缘的“0”开始编号,具有相同编号的磁道形成一个圆柱,称之为磁盘的柱面。每个磁道被划分成若干个扇区(sector),扇区是磁盘的最小组成单元,通常是512字节。
  
  系统将文件存储到磁盘上时,按柱面、磁头、扇区的方式进行,即最先是第1磁道的第一磁头下(也就是第1盘面的第一磁道)的所有扇区,然后,是同一柱面的下一磁头,一个柱面存储满后就推进到下一个柱面,直到把文件内容全部写入磁盘。读取顺序从上到下,然后从外到内。
  
  2.2 磁盘读取响应时间:
  
  寻道时间:磁头从开始移动到数据所在磁道所需要的时间,寻道时间越短,I/O操作越快,目前磁盘的平均寻道时间一般在3-15ms,一般都在10ms左右。
  
  旋转延迟:盘片旋转将请求数据所在扇区移至读写磁头下方所需要的时间,旋转延迟取决于磁盘转速。普通硬盘一般都是7200rpm,慢的5400rpm。
  
  数据传输时间:完成传输所请求的数据所需要的时间。
  
  从上面的指标来看、其实最重要的、或者说、我们最关心的应该只有两个:寻道时间;旋转延迟。为提高磁盘传输效率,软件应着重考虑减少寻道时间和延迟时间。
  
  如果一个文件存储在连续的扇区上,这样就可以减少寻道时间和旋转延迟,大大增加磁盘io读取的效率,这就是为什么大家常说随机读写速度将明显低于顺序读写。
  
  2.3 磁盘块
  
  由于扇区数目众多在寻址时比较困难,所以操作系统就将相邻的扇区组合在一起,形成一个块,再对块进行整体的操作,即块是操作系统中最小的逻辑存储单元。这样可以使操作系统忽略底层物理存储结构的设计。磁盘块是操作系统自己虚拟的概念,其大小由操作系统决定,通常一个块 = 单个扇区大小 * 2的n次方,其中n是可修改的。
  
  linux默认的块大小为4096个字节,也就是8个扇区的大小。jquery/js实现一个网页同时调用多个倒计时(最新的)
  
  最近需要网页添加多个倒计时. 查阅网络,基本上都是千遍一律的不好用. 自己按需写了个.希望对大家有用. 有用请赞一个哦!
  
  //js
  
  //js2
  
  var plugJs={
  
      stamp:0,
  
      tid:1,
  
      stampnow:Date.parse(new Date())/1000,//统一开始时间戳
  
      intervalTime:function(){
  
          if(plugJs.stamp > 0){
  
              var day =www.dasheng178.com Math.floor(plugJs.stamp / (60 * 60 * 24));
  
              var hour = Math.floor(plugJs.stamp / (60 * 60)) - (day * 24);
  
              var minute = Math.floor(plugJs.stamp / 60) - (day * 24 * 60) - (hour * 60);
  
              var second = Math.floor(plugJs.www.yinxionghui1.com/ stamp) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60);
  
              if (day <= 9) day = '0' + day;
  
              if (hour <= 9) hour = '0' + hour;
  
              if (minute <= 9) minute = '0' + minute;
  
              if (second <= 9) second = '0' + second;
  
              jQuery('.t_h_'+plugJs.tid).html(hour);
  
              jQuery('.t_m_'+plugJs.tid).html(minute);
  
              jQuery('.t_s_'+plugJs.tid).html(second);
  
              plugJs.stamp--;
  
              setTimeout('if(www.yongshi123.cn typeof(plugJs.intervalTime) www.tianshengyuLe1.cn== "function"){plugJs.intervalTime();}',1000);
  
          }
  
      },
  
      timer:function (stampend,tid){
  
          plugJs.stamp = parseInt(stampend)-parseInt(plugJs.stampnow);//剩余时间戳
  
          setTimeout('if(typeof(plugJs.intervalTime) www.shengban1.com/ == "function"){plugJs.intervalTime();}',1000);
  
      }
  
  };
  
  jQuery(document).ready(function(){
  
      var stampend = parseInt(jQuery(www.zhongxinyul2.com'.countdown_1').attr('data-time'));//灵活读取表里的结束时间戳
  
      plugJs.timer(stampend,'1');
  
  });
  
  //html 原文http://blog.csdn.net/websites/article/details/50037611
  
  <div class="time countdown_1" data-time="1449429731">
  
  <span class="t_h_1">00</span>
  
  <i class="lay_line">:</i>
  
  <span class="t_m_1">00</span>
  
  <i class="lay_line">:</i>
  
  <span class="t_s_1">00</span>
  
  </div>
  
  <div class="time countdown_2" data-time="1449456731">
  
  <span class="t_h_2">00</span>
  
  <i class="lay_line">:</i>
  
  <span class="t_m_2">00</span>
  
  <i class="lay_line">:</i>
  
  <span class="t_s_2">00</span>
  
  </div>
  
  注释:setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()。

猜你喜欢

转载自www.cnblogs.com/qwangxiao/p/10392429.html