索引失效的常见写法包括函数包列、隐式转换和前导通配符,这些操作会阻止数据库使用b-tree索引进行快速查找。具体做法是避免在索引列上使用函数或表达式,确保查询条件与索引列类型一致,以及避免以通配符开头的模糊查询。

函数包列导致索引失效
当对索引列应用函数或表达式时,数据库无法直接使用索引,因为索引存储的是原始值,而查询条件涉及的是计算后的值。例如,使用`UPPER()`函数或算术运算会导致全表扫描。

SELECT * FROM users WHERE UPPER(name) = 'JOHN'; -- 假设name列有索引,但此查询不会使用该索引 SELECT * FROM users WHERE age + 1 = 30; -- 假设age列有索引,但此查询不会使用该索引
预期结果:上述两个查询都会执行全表扫描,而不是使用索引。为了优化,可以将查询改写为不使用函数的形式,或者使用函数索引(如果数据库支持)。
隐式转换导致索引失效
当查询条件的数据类型与索引列的数据类型不一致时,数据库会进行隐式类型转换,这通常会导致索引失效。例如,将字符串与数字进行比较,或者将日期与字符串进行比较。

SELECT * FROM users WHERE phone_number = 1234567890; -- 假设phone_number列是VARCHAR类型,有索引,但此查询不会使用该索引 SELECT * FROM orders WHERE order_date = '2023-01-01'; -- 假设order_date列是DATE类型,有索引,但此查询可能不会使用该索引,取决于数据库的隐式转换行为
预期结果:第一个查询由于类型不匹配,可能会执行全表扫描。第二个查询的行为取决于数据库的具体实现,有些数据库可能会进行隐式转换并失效索引,而有些则可能优化查询。为了确保索引使用,应显式转换数据类型或使用正确的字面量类型。
前导通配符导致索引失效
在使用LIKE操作符进行模糊查询时,如果通配符%出现在模式的开头,数据库无法使用索引,因为索引是基于排序的,而前导通配符破坏了这种排序结构。例如,`LIKE '%john'`无法利用索引。
SELECT * FROM users WHERE name LIKE '%john'; -- 假设name列有索引,但此查询不会使用该索引 SELECT * FROM users WHERE name LIKE 'john%'; -- 此查询可以使用索引,因为通配符在末尾
预期结果:第一个查询会执行全表扫描,而第二个查询可以使用索引进行快速查找。为了避免前导通配符导致的索引失效,可以考虑使用全文索引或其他搜索技术,如Elasticsearch,来处理复杂的模糊查询需求。











