SQL学习指南之索引

为什么需要索引

当向一个表中插入一行时,数据库服务器不会试图将数据放到表里的任何特定的地方。服务器只是简单地将数据存放在文件中下一个可存放的位置(服务器为每张表预留了一系列空间)。查询记录时服务器需要检查表中的每一行来完成查询,当数据量很大时,服务器无法在合适的时间内完成查询。

索引是什么

  • 索引是寻找资源中特定项目的一种机制。

  • 索引是一种以特定顺序保存的专用表。不过,索引并不包含实体中的所有数据,而只包含那些用于定位表中行的列以及描述这些行的物理位置的信息。

  • 索引的作用就是便捷化检索表中行和列的子集,而不需要检查表中的每行。

  • 唯一索引,除提供常规索引的好处外,还提供一种机制限制索引列出现重复值。

  • 多列索引,跨越多列的索引。若需要保证充分的响应时间,可以基于不同顺序为同一列集创建多列索引。

索引类型

B树索引(平衡树索引)

  • B树索引以树结构组织,它有一个或多个分支节点,分支节点又指向单级的叶节点。分支节点用于遍历树,叶节点则保存真正的值和位置信息。
  • 当对特定表进行插入、更新和删除操作时,服务器会通过增加或删除分支节点重新将值分配得更加均匀。通过保持树的均匀,不需要遍历多层分支节点,服务器旧能够快速到达叶节点查找到需要的值。
  • MySQL、Oracle、SQL Server默认都是B树索引。
  • B树索引擅长于处理包含许多不同值的列,在处理允许少量不同值的列时会因为难以保持树的平衡而变得很难用。

位图索引

  • 位图索引为存储在某列中的每个值生成一个位图。
  • 位图索引适用于包含少量值却占据大量行(低基数)的列,例如数据仓库环境。当列中存储的值的数目攀升到相对行数太高时(高基数),这种策略会失效,因为服务器需要维护太多的位图。

文本索引

  • 如果数据库中存储文档,需要允许用户在文档中查找单词或短语时,使用文本索引。
  • MySQL和SQL Server提供了全文索引(MySQL中仅MyISAM存储引擎中可以使用全文索引),Oracle提供了Oracle Text工具集。

如何使用索引

  • 服务器通常首先利用索引快速定位特定表中的行,之后再访问相关表提取用户请求的补充信息。
  • 使用查询优化器、分析执行计划

索引的不足

  • 每个索引事实上都是一个表(一种特殊类型的表,但也是表)。因此,每次在对表添加或删除时,表中的所有索引必须被修改;当更新行时,收到影响的列的任何索引也必须被修改。索引越多,服务器就需要做越多的工作来保持所有模式对象最新,这样将会拖慢服务器处理任务的速度。
  • 索引需要磁盘空间,需要人去管理。因此对于索引的最佳策略是:仅当出现清晰需求时才添加索引。如果有特殊目的需要索引,比如每月例行维护程序,用户可以添加索引,运行程序,然后删除索引,下次需要时再重复一遍。
  • 应避免使用太多或太少索引,默认使用策略如下:
    • 确保所有主键列被索引(大部分服务器会在创建主键约束时自动生成唯一索引)。针对多列主键,考虑为主键列的子集构建索引,或者以与主键约束定义不同的顺序为所有主键另外生成索引。
    • 为所有被外键约束引用的列创建索引。服务器在删除父行时会查找以确保没有子行存在,为此它必须发处一个查询搜索列中的特定值,如果该列没有索引,那么服务器必须扫描整个表。
    • 索引那些被频繁检索的列。除了短字符串(3~50个字符)列,大多数日期列也可以作为候选。