CSDN|别再一知半解啦,索引其实就这么回事!( 二 )


如此一来 , 可以看出索引的一大好处是如其概念中所提及的 , 使用索引后可以不用扫描全表来定位某行的数据 , 而是先通过索引表找到该行数据对应的物理地址然后访问相应的数据 。 这样的方式自然减少了服务器在响应时所需要对数据库扫描的数据量 。
不仅如此 , 在执行数据库的范围查询时 , 若不使用索引 , 那么MySQL会先扫描数据库的所有行数据并从中筛选出目标范围内的行记录 , 将这些行记录进行排序并生成一张临时表 , 然后通过临时表返回用户查询的目标行记录 。 这个过程会涉及到临时表的建立和行记录的排序 , 当目标行记录较多的时候 , 会大大影响范围查询的效率 。
所以当添加索引时 , 由于索引本身具有的顺序性 , 使得在进行范围查询时 , 所筛选出的行记录已经排好序 , 从而避免了再次排序和需要建立临时表的问题 。
同时 , 由于索引底层实现的有序性 , 使得在进行数据查询时 , 能够避免在磁盘不同扇区的随机寻址 。 使用索引后能够通过磁盘预读使得在磁盘上对数据的访问大致呈顺序的寻址 。 这本质上是依据局部性原理所实现的 。
局部性原理:当一个数据被用到时 , 其附近的数据也通常会马上被使用 。 程序运行期间所需要的数据通常比较集中 。 由于磁盘顺序读取的效率很高(不需要寻道时间 , 只需很少的旋转时间), 因此对于具有局部性的程序来说 , 磁盘预读可以提高I/O效率 。
磁盘预读要求每次都会预读的长度一般为页的整数倍 。 而且数据库系统将一个节点的大小设为等于一个页 , 这样每个节点只需要一次 I/O 就可以完全载入 。 这里的页是通过页式的内存管理所实现的 , 概念在这里简单提一嘴 。
分页机制就是把内存地址空间分为若干个很小的固定大小的页 , 每一页的大小由内存决定 。 这样做是为了从虚拟地址映射到物理地址 , 提高内存和磁盘的利用率 。
所以呢 , 总结一下 。 索引的存在具有很大的优势 , 主要表现为以下三点:

  • 索引大大减少了服务器需要扫描的数据量
  • 索引可以帮助服务器避免排序和临时表
  • 索引可以将随机 I/O 变成顺序 I/O
以上三点能够大大提高数据库查询的效率 , 优化服务器的性能 。 因此一般来说 , 为数据库添加高效的索引对数据库进行优化的重要工作之一 。
不过 , 凡事都有两面性 。 索引的存在能够带来性能的提升 , 自然在其它方面也会付出额外的代价 。
索引本身以表的形式存储 , 因此会占用额外的存储空间;
索引表的创建和维护需要时间成本 , 这个成本随着数据量增大而增大;
构建索引会降低数据的修改操作(删除 , 添加 , 修改)的效率 , 因为在修改数据表的同时还需要修改索引表;
所以对于非常小的表而言 , 使用索引的代价会大于直接进行全表扫描 , 这时候就并不一定非得使用索引了 。 没办法 , 成年人的世界总是这么的趋利避害 。
逻辑分类从逻辑的角度来对索引进行划分的话 , 可以分为单列索引、全文索引、组合索引和空间索引 。 其中单列索引又可分为主键索引、唯一索引和普通索引 。 这里的逻辑可以理解为从 SQL 语句的角度 , 或者是从数据库关系表的角度 。 下面就简单介绍这些索引的作用和用法 , 以及在修改表的时候如何添加索引 。 主键索引即主索引 , 根据主键建立索引 , 不允许重复 , 不允许空值;
主键:数据库表中一列或列组合(字段)的值 , 可唯一标识表中的每一行 。
加速查询 + 列值唯一(不可以有null)+ 表中只有一个
ALTER TABLE 'table_name' ADD PRIMARY KEY pk_index('col');唯一索引用来建立索引的列的值必须是唯一的 , 允许空值 。 唯一索引不允许表中任何两行具有相同的索引值 。 比方说 , 在 employee 表中职员的姓 name 上创建了唯一索引 , 那么就表示任何两个员工都不能同姓 。


推荐阅读