数据库开发小知识普及五--SQL什么情况下不走索引呢?

本文探讨了索引逻辑失效和物理失效的常见原因,包括不当使用索引、类型转换、复杂运算、统计信息不准确等,以及move操作和分区表对索引的影响。提供了解决这些问题的建议,帮助开发者优化查询性能。

1.索引逻辑失效

(1)用索引反而代价变高

当应用索引检索数据,返回大量记录时,这时候用索引肯定有错,索引范围查询访问一般适合返回少量记录的情况,否则全表扫描或者全索引扫描就可以。

(2)发生索引列的类型转换

在表字段设计时,有一个非常重要的原则,什么类型的字段存什么类型的值,否则就会发生隐式类型转换。例如:

Create table t_col_type(id varchar2(20));

Select * from t_col_type where id=6;

这种情况,id列会被to_number(id)=6。无法使用索引。

(3)对索引进行了各种运算,或者对索引列使用函数

Select * from t where object_id/2=:id;

Select * from t where upper(name)='ABC';

(4)统计信息不准确

当表的统计信息不准确时,可能导致SQL不走索引,或者走错误的索引,SQL变慢,因此定时收集统计信息很重要。

2.索引物理失效

(1)move操作会导致索引失效

Alter table t move;--move是一个危险系数非常高的操作,它可以收缩表降低高水位,却会导致索引失效,需要重建索引。

(2)分区表导致全局索引失效的操作

所有的全局索引,truncate、drop、split、exchange分区,会导致索引失效。split分区也会导致局部索引失效。

### MySQL 中 `varchar` 字段比较时索引失效的条件分析 在 MySQL 数据库中,当涉及 `varchar` 类型字段之间的比较操作时,可能存在一些特定场景使得原本有效的索引变得可用。以下是几个常见的导致索引失效的具体原因及其背后的原理说明。 #### 1. **数据类型一致引发隐式转换** 如果两个 `varchar` 字段之间存在数据类型差异(即使是细微的同),MySQL 可能会对其中一个字段进行隐式类型转换以实现两者间的比较。这种情况下,即使目标字段上有索引,也可能因隐式转换而导致索引失效[^2]。例如: ```sql SELECT * FROM orders WHERE CAST(order_id AS SIGNED) = another_order_id; ``` 在此查询中,`CAST(order_id AS SIGNED)` 将原始字符串类型的 `order_id` 转换成了整数类型再做对比运算,这一步骤破坏了原有基于字符型索引的应用环境,进而使优化器放弃使用该索引。 #### 2. **跨编码集匹配问题** 同字符集或排序规则(colation)下存储的内容即便表面看起来相似甚至完全一样,在底层表示层面却未必能够直接相互映射。假如两列分别采用了 utf8 和 latin1 编码方案,则它们彼此间的关系就超出了单纯意义上的“等于”范畴之外,此时为了确保结果准确性,系统采取更为保守的做法—即禁用任何可能依赖于单一编码特性的快速定位手段(也就是所谓的B-tree索引)[^3]。 #### 3. **模糊搜索模式限定符影响** 当我们运用通配符 `%`, `_` 实施前缀匹配(`LIKE '%abc%'`)或是其他形式较为灵活但代价高昂的正则表达式筛选(`REGEXP 'pattern'`)时,除非非常特殊的例外状况(如仅限左端固定的短语开头部分才允许利用常规索引辅助加速查找速度外),一般而言都会致使整个扫描流程退化回全量遍历状态下去逐一核验每条记录是否符合条件[^1]。 #### 4. **复合索引顺序当** 假设有这样一个组合索引 `(col_a, col_b)` 存在于某张表格之上,那么只有当我们的询问请求严格遵循先指定 `col_a` 再跟进 `col_b` 的层次关系才能充分发挥出这个多维结构的优势;反之倘若跳跃性地越过前者径直指向后者的话 (`WHERE col_b = ... AND col_a <> ...`) ,后续关联起来的部分自然也无法享受到预建路径所带来的便利之处了。 --- ### 结论 综上所述,对于 `varchar` 类型字段来说,其索引会在如下几种典型情境下面临失效风险:一是由于显式/隐式的类型转变打破了原有的物理布局连续性;二是跨越异构化的字符集合尝试建立联系增加了复杂度以至于难以维持高效检索策略;三是滥用非精确性质的操作符扰乱了既定次序安排等等。为了避免这些问题的发生,建议开发者们始终注意保持一致性原则贯穿始终,并且谨慎选用合适的语法构造来达成目的。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值