覆盖索引(covering index)存储一些属性的值以及指向记录的指针。存储附加的属性值对于辅助索引是非常有用的,因为它们使我们仅仅使用索引就能够回答一些查询,甚至不需要找到实际的记录。//由此可见,覆盖索引是一种辅助索引,也是一种多码索引
也就是说,覆盖索引包含了查询所需要的所有字段,因此查询可以完全通过索引来满足,而不需要访问表中的数据行。
怎么理解这样一种索引方式呢?
下边举例来说明一下,假如有一张包含以下字段的 Employees 表:
Employees(EmployeeID, FirstName, LastName, Department, Salary)
如果我们经常需要执行如下查询:
SELECT EmployeeID, FirstName, LastName FROM Employees WHERE Department = 'Sales';
当使用普通索引时,我们可以在 Department 字段上创建一个普通索引:
CREATE INDEX idx_department ON Employees(Department);
那么查询时,索引能快速找到所有 Department 为 Sales 的记录,但仍需要访问表中的数据页来获取 EmployeeID,FirstName,LastName。//这一过程也叫回表操作,辅助索引一般情况下都需要进行回表操作
所谓"回表”,是指在使用索引进行查询时,需要通过索引找到所需的数据行的行标识(Row lD),然后再根据这个行标识访问实际的数据页,从而获取查询所需的完整数据。
如果使用覆盖索引,那么就可以避免上述的回表操作,覆盖索引的创建是这样的:
CREATE INDEX idx_department_cover ON Employees(Department, EmployeeID, FirstName, LastName);
查询时,所有所需字段都在索引中,因此可以直接通过索引返回 EmployeeID,FirstName, LastName,不需要访问数据页。由于所有查询字段都在索引中,无需访问数据页,从而减少了 I/O 操作和内存占用。
那么覆盖索引有什么局限性呢?
虽然使用覆盖索引能提升查询性能,避免回表操作。但是一个技术总会存在优劣两个方面,因为覆盖索引包含查询的所有列,因此索引本身变得更大,占用了更多的存储空间。此外,插入、更新和删除操作需要维护更大的索引结构,增加了这些操作的成本。每次写操作都需要更新相关的覆盖索引,导致性能开销。
因此,我们需要根据具体应用场景和查询模式,在性能和开销之间取得平衡,合理设计和使用覆盖索引。
至此,全文结束。