组合索引

单列索引

定义

单列索引是在数据库表的某一个列上创建的索引。它就像是在一本书的某一个章节后面单独制作的一个小目录,通过这个小目录可以快速定位到该章节内的特定内容。

举例

假设有一个员工信息表 employees,包含 idnameagedepartment 等列。现在为 name 列创建一个单列索引。

CREATE INDEX idx_name ON employees (name);

当我们执行如下查询时:

SELECT * FROM employees WHERE name = '张三';

数据库可以利用 idx_name 这个单列索引,快速定位到 name 为 '张三' 的员工记录,而不需要全表扫描,从而提高查询效率。

特点

  • 针对性强:只针对创建索引的列进行优化。如果查询条件不是该列,索引就无法发挥作用。例如,当查询 SELECT * FROM employees WHERE age = 25; 时,idx_name 索引就不会被使用。
  • 灵活性高:当只需要根据单个列进行查询时,单列索引可以很好地满足需求。

组合索引

定义

组合索引是在数据库表的多个列上创建的索引。它类似于一本书的综合目录,通过多个关键词来定位内容,多个列的顺序在索引创建时就已经确定,查询时需要按照这个顺序使用列。

举例

还是以 employees 表为例,为 departmentage 列创建一个组合索引。

CREATE INDEX idx_department_age ON employees (department, age);

当我们执行如下查询时:

SELECT * FROM employees WHERE department = '技术部' AND age = 30;

数据库可以利用 idx_department_age 组合索引,先根据 department 列筛选出 '技术部' 的员工,再在这些员工中根据 age 列筛选出年龄为 30 的员工,大大减少了查询的范围,提高了查询效率。

特点

  • 多条件查询优化:适用于经常需要同时根据多个列进行查询的场景。例如,上述查询中同时使用了 departmentage 列作为查询条件,组合索引可以一次性处理多个条件。
  • 索引顺序敏感:组合索引中的列顺序非常重要。如果查询条件不按照索引列的顺序,索引可能无法完全发挥作用。例如,执行 SELECT * FROM employees WHERE age = 30 AND department = '技术部';,虽然结果一样,但数据库可能无法很好地利用 idx_department_age 索引,因为查询条件的列顺序与索引列顺序不一致。
  • 覆盖范围广:如果查询的列都包含在组合索引中,数据库可以直接从索引中获取数据,而不需要再去查询实际的表记录,进一步提高查询效率。例如,执行 SELECT department, age FROM employees WHERE department = '技术部' AND age = 30;,由于查询的列 departmentage 都在组合索引中,数据库可以直接从索引中获取数据。

区别总结

  • 查询场景适用性:单列索引适用于只根据单个列进行查询的场景;组合索引适用于经常需要同时根据多个列进行查询的场景。
  • 索引效率:在多条件查询时,组合索引通常比单列索引效率更高,因为它可以一次性处理多个条件,减少查询范围。但如果查询条件不符合组合索引的列顺序,可能会影响索引的使用效率。
  • 空间占用:组合索引需要存储多个列的索引信息,因此占用的磁盘空间通常比单列索引大。

按照上述说法,建一个部门和年龄的组合索引,如果sql查询只用到部门或者年龄的条件查询,会触发组合索引么
是否能触发部门和年龄的组合索引,取决于组合索引中列的顺序以及查询条件,以下为你分情况详细说明:

组合索引创建示例

假设我们在 employees 表上创建了部门(department)和年龄(age)的组合索引,SQL 语句如下:

CREATE INDEX idx_department_age ON employees (department, age);

情况一:查询只使用组合索引的最左列(部门)

当 SQL 查询只使用 department 作为查询条件时,通常可以触发组合索引。

  • 示例查询
SELECT * FROM employees WHERE department = '技术部';
  • 原理:组合索引遵循最左前缀原则,即从索引的最左边列开始使用。在这个例子中,索引的最左列是 department,所以数据库可以使用该组合索引快速定位到 department 为 '技术部' 的记录,就像在一个按部门和年龄排序的列表中,先根据部门名称快速找到对应的部分。

情况二:查询只使用组合索引非最左列(年龄)

当 SQL 查询只使用 age 作为查询条件时,一般不能触发组合索引。

  • 示例查询
SELECT * FROM employees WHERE age = 30;
  • 原理:由于最左前缀原则,数据库在使用组合索引时需要从最左列开始匹配。在这个查询中,只使用了 age 列,没有从 department 列开始,所以数据库无法利用该组合索引进行高效查询,可能会选择全表扫描。

情况三:查询条件中先使用非最左列,再使用最左列

如果查询条件中先使用了 age,再使用 department,也无法有效利用组合索引。

  • 示例查询
SELECT * FROM employees WHERE age = 30 AND department = '技术部';
  • 原理:虽然查询条件包含了组合索引中的两列,但由于没有从最左列 department 开始使用,数据库无法按照组合索引的顺序进行匹配,因此组合索引不能发挥作用。不过,有些数据库可能会对查询语句进行优化,将查询条件重新排序,但不是所有数据库都能做到这一点。

总结

对于 (department, age) 的组合索引,只有当查询条件从最左列 department 开始使用时,才能触发该组合索引进行高效查询。如果只使用 age 列作为查询条件,通常无法触发该组合索引。

那如果组合索引有三个字段,单独使用中间的字段查询,会触发组合索引么

一般情况下,如果组合索引有三个字段,单独使用中间的字段查询,是不会触发该组合索引的,下面结合最左前缀原则为你详细解释,并给出示例。

最左前缀原则

组合索引遵循最左前缀原则,即数据库在使用组合索引进行查询时,必须从索引的最左边的列开始依次使用,不能跳过前面的列直接使用后面的列。如果查询条件不满足最左前缀原则,组合索引将无法被有效利用。

示例说明

假设我们有一个 orders 表,包含 customer_idorder_dateorder_amount 三列,并且创建了一个组合索引:

CREATE INDEX idx_customer_date_amount ON orders (customer_id, order_date, order_amount);

单独使用中间字段查询(不触发组合索引)

如果我们单独使用中间的 order_date 字段进行查询,如下所示:

SELECT * FROM orders WHERE order_date = '2024-01-01';

这种情况下,数据库无法利用 idx_customer_date_amount 组合索引。因为根据最左前缀原则,使用该组合索引时需要从 customer_id 列开始,而这个查询直接使用了中间的 order_date 列,跳过了 customer_id 列,所以组合索引不会被触发,数据库可能会选择全表扫描来执行这个查询。

满足最左前缀原则(触发组合索引)

如果查询条件满足最左前缀原则,组合索引就可以被使用。例如:

SELECT * FROM orders WHERE customer_id = 1 AND order_date = '2024-01-01';

这个查询从组合索引的最左列 customer_id 开始,然后使用了 order_date 列,满足最左前缀原则,数据库可以利用 idx_customer_date_amount 组合索引来提高查询效率。

特殊情况

虽然一般情况下单独使用中间字段不会触发组合索引,但在某些数据库的特定优化策略下,可能会有一些特殊处理。不过这种情况比较少见,而且不同数据库的实现也不同。为了确保查询能够利用组合索引,最好还是按照最左前缀原则来编写查询条件。

综上所述,通常单独使用组合索引中间的字段查询不会触发该组合索引。

posted @ 2021-04-29 17:13  皇问天  阅读(929)  评论(0)    收藏  举报