组合索引
单列索引
定义
单列索引是在数据库表的某一个列上创建的索引。它就像是在一本书的某一个章节后面单独制作的一个小目录,通过这个小目录可以快速定位到该章节内的特定内容。
举例
假设有一个员工信息表 employees
,包含 id
、name
、age
、department
等列。现在为 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
表为例,为 department
和 age
列创建一个组合索引。
CREATE INDEX idx_department_age ON employees (department, age);
当我们执行如下查询时:
SELECT * FROM employees WHERE department = '技术部' AND age = 30;
数据库可以利用 idx_department_age
组合索引,先根据 department
列筛选出 '技术部' 的员工,再在这些员工中根据 age
列筛选出年龄为 30 的员工,大大减少了查询的范围,提高了查询效率。
特点
- 多条件查询优化:适用于经常需要同时根据多个列进行查询的场景。例如,上述查询中同时使用了
department
和age
列作为查询条件,组合索引可以一次性处理多个条件。 - 索引顺序敏感:组合索引中的列顺序非常重要。如果查询条件不按照索引列的顺序,索引可能无法完全发挥作用。例如,执行
SELECT * FROM employees WHERE age = 30 AND department = '技术部';
,虽然结果一样,但数据库可能无法很好地利用idx_department_age
索引,因为查询条件的列顺序与索引列顺序不一致。 - 覆盖范围广:如果查询的列都包含在组合索引中,数据库可以直接从索引中获取数据,而不需要再去查询实际的表记录,进一步提高查询效率。例如,执行
SELECT department, age FROM employees WHERE department = '技术部' AND age = 30;
,由于查询的列department
和age
都在组合索引中,数据库可以直接从索引中获取数据。
区别总结
- 查询场景适用性:单列索引适用于只根据单个列进行查询的场景;组合索引适用于经常需要同时根据多个列进行查询的场景。
- 索引效率:在多条件查询时,组合索引通常比单列索引效率更高,因为它可以一次性处理多个条件,减少查询范围。但如果查询条件不符合组合索引的列顺序,可能会影响索引的使用效率。
- 空间占用:组合索引需要存储多个列的索引信息,因此占用的磁盘空间通常比单列索引大。
按照上述说法,建一个部门和年龄的组合索引,如果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_id
、order_date
、order_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
组合索引来提高查询效率。
特殊情况
虽然一般情况下单独使用中间字段不会触发组合索引,但在某些数据库的特定优化策略下,可能会有一些特殊处理。不过这种情况比较少见,而且不同数据库的实现也不同。为了确保查询能够利用组合索引,最好还是按照最左前缀原则来编写查询条件。
综上所述,通常单独使用组合索引中间的字段查询不会触发该组合索引。