有一天我遇到了一个同事的求助,他让我帮忙优化一个SQL,这个SQL执行时间很长。于是我查询了执行计划,发现这个SQL竟然要进行一次全表扫描。当时我查看了表的定义,发现在where子句中的条件列上是建了索引的,那为什么执行计划会显示全表扫描呢。这个问题困扰了我很长时间,于是后来我又看了看表的定义,发现了问题的根本所在,作为条件的字段是varchar,而SQL语句中的条件是一串数字!这样的话就会造成索引不可用,处理方法也很简单,加上一对单引号就可以了。
下面是语句和执行计划(这里做了简单化处理,只需要注意全表扫描就可以):
1
select * from TEST t where t.spec_prpty_id = 3303;
Plan hash value: 1357081020
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| TEST | 1 | 5 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_NUMBER("T"."SPEC_PRPTY_ID")=3303)
这是添加过单引号的执行计划:
Plan hash value: 1128569081
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 5 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| IDX_TEST | 1 | 5 | 1 (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("T"."SPEC_PRPTY_ID"='3303')
可以看出使用了索引,如果该表数据量大的话,那么这样的效率提升是非常可观的。
这个例子很简单,很多高手也会嗤之以鼻,但是秉承着从细微处入手学习Oracle的信念的我,还是从这里得到了一个知识点:一下几种情况索引不会被使用:
1 不等于操作不能用于索引
2 经过普通或者函数运算的索引列不能使用索引
3 含前向模糊
4 索引列为空
5 数值比较时左右类型不同,相当于做了隐式类型转换
6 给索引查询的值是未知字段,而不是已知数
一定要注意,慎之又慎的写SQL。
分享到:
相关推荐
在遇到Oracle不使用索引的情况时,不应盲目地强制使用索引。应先分析查询计划,理解Oracle优化器的选择,并进行性能测试,确保使用索引能带来显著的性能提升。在某些情况下,优化SQL语句结构、调整索引策略,或者...
- **可用性**:相比全局索引,本地索引具有更高的可用性。这是因为对于分区表的操作(如truncate、move或shrink)通常只会影响本地索引的一个分区,而不会影响全局索引的所有分区。 - **位图索引**:位图索引只能是...
而对于多列查询,尤其是涉及到联合索引的情况,非聚集索引可能更优。 - **更新性能**:由于聚集索引会影响数据行的物理顺序,因此在插入、删除或更新操作时可能会引起更多的页面分裂或重组,而非聚集索引则相对较少...
在实践中,聚集索引和非聚集索引的使用规则很容易被忽视或不能根据实际情况进行综合分析。例如,主键就是聚集索引是一种误区。虽然 SQL SERVER 默认是在主键上建立聚集索引的,但这并不意味着主键一定是聚集索引。 ...
- **测试索引效果**:当新建一个索引时,可以先将其设置为不可见,这样在不影响当前查询计划的情况下,可以观察新索引是否提高了查询效率。 - **减少风险**:在高并发的线上环境中,直接删除或创建索引可能会导致...
Oracle索引被限制的一些情况 Oracle索引是关系数据库管理系统中用于提高查询效率的一种机制,但是索引的使用也存在一些限制。本文将详细介绍一些常见的限制情况,帮助开发人员更好地使用索引,提高查询效率。 限制...
### 接口响应慢的处理办法—MySQL索引不生效情况分析 #### 一、引言 在数据库操作中,索引是提高查询性能的重要工具之一。然而,在实际使用过程中,由于各种原因,索引可能会出现不生效的情况,从而导致查询效率...
在Oracle 9i之前,判断一个索引是否有效并不容易,导致很多数据库中存在未使用的、浪费资源的索引。 在Oracle 9i中,通过`ALTER INDEX`命令可以开启或关闭对索引使用情况的监控。要开始监控某个索引,可以使用如下...
主键索引:一种特殊的唯一索引,不允许有空值 联合索引:索引列有多个字段,使用时需要满足最左前缀原则 普通索引 这是最基本的索引,它没有任何限制。它有以下几种创建方式: 1.创建索引 代码如下: CREATE ...
参数index默认情况下是True,意味着如果在调用to_csv时不添加index参数,或者直接写为index=True,那么导出的CSV文件中将包含索引列。而设置为index=False后,输出的CSV文件就不会有索引列。 例如,假设我们有一个...
反向键索引适用于排序顺序与键值顺序相反的情况,如主键自增的情况。 当涉及数据操作,如删除、插入和更新时,索引的影响不容忽视。删除操作在Oracle中会产生UNDO数据,这需要额外的REDO日志来维护,导致较高的性能...
虽然默认情况下主键上会建立聚焦索引,但这并不意味着所有情况下都应该这样做。应该根据实际需求来决定是否在主键上建立聚焦索引。 - **误区二**:**过多使用聚焦索引**。虽然聚焦索引可以提高某些查询的性能,但...
- **索引组织表(Index-Organized Table, IOT)**:数据直接存储在索引结构中,适合主键访问密集的情况。 - **B*树聚簇索引**:一个键值对应一个数据块,包含该键值相关的一组行。 - **降序索引**:数据按照降序...
在没有索引的情况下,数据库系统执行查询时必须进行全表扫描,即逐行检查直到找到所需数据,这在数据量大时效率极低。而使用了索引,数据库可以快速定位到所需数据,显著提高了查询速度。 索引的工作原理类似于书籍...
对于更复杂的情况,比如在图书馆中查找书籍,图书会被按照类别分门别类地存放,这就形成了一种树状结构的索引系统。每本书都会被分配到相应的类别中,每个类别下面还有子类别,以此类推。这种方式类似于数据库中的B+...
在这种情况下,即使我们执行一个查询语句,优化器也不会使用该索引: SQL> set autot trace exp SQL> select * from t_test1 where table_name like 'HR%'; Execution Plan -------------------------------------...
5. **优化索引**:在系统运行过程中,可能需要监控索引的使用情况,根据实际性能调整索引策略,例如添加、删除或重建索引。 在给定的压缩包文件中,`getidx.pbl`、`getidx.pbt`和`getidx.pbw`可能是某种数据库或...
这些特点使得B+树非常适合用于索引构建,特别是在需要频繁顺序访问数据的情况下表现优秀。 ##### 1.4 B*树(B*-Tree) B*树是一种特殊的B树,具有以下特性: - 节点所含关键字的数量 j 满足:┌m2/3┐ - 1 ≤ j ...