面试题答案
一键面试索引列不重复值个数对查询性能的影响及优化策略
- 索引设计
- 高不重复值个数(选择性高):
- 策略:对于索引列不重复值个数较多(即选择性高)的情况,适合创建单列索引。例如,在一个
employees
表中有employee_id
列,每个员工的employee_id
都是唯一的,这种情况下为employee_id
列创建单列索引,数据库在查询时能快速定位到符合条件的记录。假设我们有如下查询:
- 策略:对于索引列不重复值个数较多(即选择性高)的情况,适合创建单列索引。例如,在一个
- 高不重复值个数(选择性高):
SELECT * FROM employees WHERE employee_id = 123;
如果employee_id
列有索引,数据库可以使用索引快速定位到employee_id
为123的记录,大大提高查询效率。
- 低不重复值个数(选择性低):
- 策略:当索引列不重复值个数较少(选择性低)时,单列索引效果不佳。可以考虑创建联合索引,但要注意索引列的顺序。例如,在一个
orders
表中有status
列,其值可能只有'completed'
、'pending'
、'cancelled'
等几种状态。如果单独为status
列创建索引,查询时数据库可能需要扫描大量记录。但如果经常有查询是基于status
和customer_id
(假设customer_id
选择性较高)的,可创建联合索引(status, customer_id)
。比如查询:
- 策略:当索引列不重复值个数较少(选择性低)时,单列索引效果不佳。可以考虑创建联合索引,但要注意索引列的顺序。例如,在一个
SELECT * FROM orders WHERE status = 'completed' AND customer_id = 456;
数据库可以先利用status
缩小范围,再通过customer_id
精准定位,提高查询效率。
2. 查询语句改写
- 高不重复值个数(选择性高):
- 策略:查询语句尽量利用索引列进行过滤。例如在上述
employees
表中,如果查询SELECT * FROM employees WHERE employee_id BETWEEN 100 AND 200;
,由于employee_id
有索引,该查询可以利用索引的范围扫描功能,高效获取结果。
- 策略:查询语句尽量利用索引列进行过滤。例如在上述
- 低不重复值个数(选择性低):
- 策略:如果索引列选择性低,避免在索引列上使用函数或表达式。例如在
orders
表的order_date
列(假设选择性低),如果有查询SELECT * FROM orders WHERE YEAR(order_date) = 2023;
,数据库无法使用order_date
列的索引,因为对order_date
使用了YEAR
函数。可以改写为SELECT * FROM orders WHERE order_date >= '2023 - 01 - 01' AND order_date < '2024 - 01 - 01';
,这样可以利用order_date
列可能存在的索引提高查询效率。
- 策略:如果索引列选择性低,避免在索引列上使用函数或表达式。例如在
总之,根据索引列不重复值个数来合理设计索引和改写查询语句,能有效提升复杂查询场景下的性能。