当前位置: 首页 > 图灵资讯 > java面试题> 金三银四精选java面试题-Mysql数据库中,什么情况下设置了索引但无法使用?

金三银四精选java面试题-Mysql数据库中,什么情况下设置了索引但无法使用?

来源:图灵教育
时间:2023-12-04 15:21:55
 

MySQL数据库中,什么情况下设置了索引但无法使用?

在MySQL数据库中,虽然设置了索引,但有时候查询执行计划并不会使用索引,导致查询性能无法得到提升。以下是一些常见的原因:

  • 不满足最左前缀原则:MySQL的联合索引遵循最左前缀原则,即只有在查询条件中使用了索引最左边的列,索引才能生效。如果查询条件没有按照索引的最左边列开始,并不会使用索引。
CREATE TABLE IndexValidation (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(50),
  age INT,
  email VARCHAR(100),
  created_at TIMESTAMP
);

INSERT INTO IndexValidation (name, age, email, created_at) VALUES
    ('Alice', 25, 'alice@example.com', NOW()),
    ('Bob', 30, 'bob@example.com', NOW()),
    ('Charlie', 35, 'charlie@example.com', NOW());
CREATE INDEX idx_name_age ON IndexValidation (name, age);

EXPLAIN SELECT * FROM IndexValidation WHERE age = 25;
  • 使用函数或表达式:当查询条件中使用了函数或表达式时,索引可能无法生效。因为索引只能在使用了相同的函数或表达式后才能发挥作用。例如,在WHERE子句中使用了函数操作或进行了类型转换。
CREATE INDEX idx_created_at ON IndexValidation (created_at);

EXPLAIN SELECT * FROM IndexValidation WHERE YEAR(created_at) = 2023;
  • 隐式类型转换:如果在查询条件中将列与一个不同类型的值比较,MySQL可能会进行隐式类型转换。这可能会导致索引失效,因为MySQL无法使用索引来处理隐式类型转换后的值。
CREATE INDEX idx_age ON IndexValidation (age);

EXPLAIN SELECT * FROM IndexValidation WHERE  age = '25';
  • LIKE操作符以通配符开头:当使用LIKE操作符进行模糊匹配时,如果通配符(%)出现在搜索字符串的开头索引也会失效。因为通配符的位置决定了索引的可用性。
EXPLAIN SELECT * FROM IndexValidation WHERE name LIKE '%A';
  • 使用OR操作符:查询条件中包含OR操作符时,如果其中一个条件无法利用索引,整个查询可能会导致索引失效。对于这种情况,可以考虑使用UNION或重写查询来避免使用OR操作符。
EXPLAIN SELECT * FROM IndexValidation WHERE name = 'Alice' OR age = 30;
  • 数据量太小:对于非常小的数据表,使用索引可能不会带来性能提升,甚至可能导致性能下降。在这种情况下,MySQL可能会选择不使用索引。
  • 数据分布不均匀:如果查询的列值分布不均匀,例如只有少数几个值出现的频率很高,索引的选择性就会降低,从而导致索引失效。