MST

星途 面试题库

面试题:MySQL函数与索引结合的深度优化问题

有一个`products`表,包含`product_name`(字符串类型)、`price`(数值类型)和`category_id`(整数类型)字段。并且在`category_id`和`price`字段上分别建有单列索引。现在要查询某个特定类别中价格大于某个值的产品名称,使用函数`CONCAT(category_id, '_', price)`进行模糊查询,例如`LIKE CONCAT(1, '_', '%')`(假设1为特定类别ID),分析该函数使用如何影响查询速度?如何重新设计索引或查询来提高性能?
31.3万 热度难度
数据库MySQL

知识考点

AI 面试

面试题答案

一键面试

函数使用对查询速度的影响

  1. 索引失效:在WHERE子句中使用函数CONCAT(category_id, '_', price),数据库无法使用已有的category_idprice单列索引。因为索引是基于列的原始值建立的,函数操作会改变列值,导致数据库必须全表扫描products表来满足LIKE CONCAT(1, '_', '%')这样的查询条件,查询速度显著降低。

提高性能的方法

重新设计索引

  1. 联合索引:可以创建一个联合索引(category_id, price)。这是因为联合索引的顺序很重要,最左前缀原则决定了查询时如果WHERE子句的条件从左到右匹配联合索引的列顺序,索引才能有效利用。对于查询特定类别中价格大于某个值的情况,category_idprice的顺序能满足需求。例如:
CREATE INDEX idx_category_price ON products (category_id, price);
  1. 覆盖索引:如果查询只需要product_name字段,可以考虑创建覆盖索引。覆盖索引包含查询所需的所有字段,这样数据库可以直接从索引中获取数据,避免回表操作。例如:
CREATE INDEX idx_covering ON products (category_id, price, product_name);

重新设计查询

  1. 拆分查询:避免在WHERE子句中使用函数,可以先根据category_id过滤数据,然后再对价格进行过滤,最后通过应用层代码拼接字符串进行模糊查询。例如在SQL中可以这样写:
SELECT product_name, CONCAT(category_id, '_', price) AS combined
FROM products
WHERE category_id = 1 AND price > some_value;

然后在应用层代码中对combined字段进行LIKE操作。这样利用了已有的category_idprice索引,提高了查询效率。