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


所以当添加索引时,由于索引本身具有的顺序性,使得在进行范围查询时,所筛选出的行记录已经排好序,从而避免了再次排序和需要建立临时表的问题 。
同时,由于索引底层实现的有序性,使得在进行数据查询时,能够避免在磁盘不同扇区的随机寻址 。使用索引后能够通过磁盘预读使得在磁盘上对数据的访问大致呈顺序的寻址 。这本质上是依据局部性原理所实现的 。

局部性原理:当一个数据被用到时,其附近的数据也通常会马上被使用 。程序运行期间所需要的数据通常比较集中 。由于磁盘顺序读取的效率很高(不需要寻道时间,只需很少的旋转时间),因此对于具有局部性的程序来说,磁盘预读可以提高I/O效率 。
磁盘预读要求每次都会预读的长度一般为页的整数倍 。而且数据库系统将一个节点的大小设为等于一个页,这样每个节点只需要一次 I/O 就可以完全载入 。这里的页是通过页式的内存管理所实现的,概念在这里简单提一嘴 。
分页机制就是把内存地址空间分为若干个很小的固定大小的页,每一页的大小由内存决定 。这样做是为了从虚拟地址映射到物理地址,提高内存和磁盘的利用率 。
所以呢,总结一下 。索引的存在具有很大的优势,主要表现为以下三点:
  • 索引大大减少了服务器需要扫描的数据量
  • 索引可以帮助服务器避免排序和临时表
  • 索引可以将随机 I/O 变成顺序 I/O
以上三点能够大大提高数据库查询的效率,优化服务器的性能 。因此一般来说,为数据库添加高效的索引对数据库进行优化的重要工作之一 。
不过,凡事都有两面性 。索引的存在能够带来性能的提升,自然在其它方面也会付出额外的代价 。
索引本身以表的形式存储,因此会占用额外的存储空间;
索引表的创建和维护需要时间成本,这个成本随着数据量增大而增大;
构建索引会降低数据的修改操作(删除,添加,修改)的效率,因为在修改数据表的同时还需要修改索引表;
所以对于非常小的表而言,使用索引的代价会大于直接进行全表扫描,这时候就并不一定非得使用索引了 。没办法,成年人的世界总是这么的趋利避害 。
别再一知半解啦,索引其实就这么回事

文章插图
 
逻辑分类从逻辑的角度来对索引进行划分的话,可以分为单列索引、全文索引、组合索引和空间索引 。其中单列索引又可分为主键索引、唯一索引和普通索引 。这里的逻辑可以理解为从 SQL 语句的角度,或者是从数据库关系表的角度 。下面就简单介绍这些索引的作用和用法,以及在修改表的时候如何添加索引 。
 
主键索引即主索引,根据主键建立索引,不允许重复,不允许空值;
主键:数据库表中一列或列组合(字段)的值,可唯一标识表中的每一行 。
加速查询 + 列值唯一(不可以有)+ 表中只有一个
ALTER TABLE 'table_name' ADD PRIMARY KEY pk_index('col'); 
唯一索引用来建立索引的列的值必须是唯一的,允许空值 。唯一索引不允许表中任何两行具有相同的索引值 。比方说,在 employee 表中职员的姓 name 上创建了唯一索引,那么就表示任何两个员工都不能同姓 。
加速查询 + 列值唯一(可以有)
ALTER TABLE 'table_name' ADD UNIQUE index_name('col'); 
普通索引用表中的普通列构建的索引,没有任何限制 。
仅加速查询
ALTER TABLE 'table_name' ADD INDEX index_name('col'); 
全文索引用大文本对象的列构建的索引
ALTER TABLE 'table_name' ADD FULLTEXT INDEX ft_index('col'); 
组合索引用多个列组合构建的索引,这多个列中的值不允许有空值 。
多列值组成一个索引,专门用于组合搜索,其效率大于索引合并 。
ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3');在对多列组合建立索引时,会遵循「最左前缀」原则 。
最左前缀原则:顾名思义,就是最左优先,上例中我们创建了 (col1, col2, col3) 多列索引,相当于创建了 (col1) 单列索引,(col1, col2) 组合索引以及 (col1, col2, col3) 组合索引 。
所以当我们在创建多列索引时,要根据业务场景,将 where 子句中使用最频繁的一列放在最左边 。


推荐阅读