IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

Oracle字符类型存数字及查询数字时使用单引号走不走索引的问题

信春哥,系统稳,闭眼上线不回滚! 2016-02-14 00:06:24 累计浏览 2,657 次
本机暂存

新上线的系统很多数字类型的字段都是使用varchar2类型存放,要转换成number类型时,和开发人员对number类型的字段在查询时加上单引号走不走索引的问题产生了分歧,大家都知道,如果使用char类型存放数字,在查询时如果不加单引号是不会走索引的,测试信息如下,数据库版本11.2.0.4.0。

创建测试表如下。

01SQL> conn dbdream/dbdream
02Connected.
03SQL>
04
05SQL> create table ind_text as select object_id,object_name from dba_objects;
06
07Table created.
08
09SQL> ALTER TABLE IND_TEXT ADD OBJECT_CHAR VARCHAR2(22);
10
11Table altered.
12
13SQL> UPDATE IND_TEXT SET OBJECT_CHAR=OBJECT_ID;
14
1590743 rows updated.
16
17SQL> COMMIT;
18
19Commit complete.
20
21SQL> ALTER TABLE IND_TEXT MOVE;
22
23Table altered.

创建索引。

01SQL> create index ind_OBJECT_ID on ind_text(OBJECT_ID);
02
03Index created.
04
05SQL> create index ind_OBJECT_NAME on ind_text(OBJECT_NAME);
06
07Index created.
08
09SQL> CREATE INDEX IND_OBJECT_CHAR ON IND_TEXT(OBJECT_CHAR);
10
11Index created.

现在OBJECT_ID字段是用number类型存放数字,OBJECT_CHAR字段使用varchar2类型存放数字,通过下面的测试可以看到如果查询OBJECT_CHAR字段字段,不加单引号是不会走索引的。

01SQL> SELECT OBJECT_CHAR,OBJECT_NAME FROM IND_TEXT WHERE OBJECT_CHAR='100832';
02
03OBJECT_CHAR          OBJECT_NAME
04-------------------- ------------------
05100832               ORD_ORD_DTL_D
06
07Execution Plan
08----------------------------------------------------------
09Plan hash value: 1825303736
10
11-----------------------------------------------------------------------------------------------
12| Id  | Operation                   | Name            | Rows  | Bytes | Cost (%CPU)| Time     |
13-----------------------------------------------------------------------------------------------
14|   0 | SELECT STATEMENT            |                 |     1 |    78 |     1   (0)| 00:00:01 |
15|   1 |  TABLE ACCESS BY INDEX ROWID| IND_TEXT        |     1 |    78 |     1   (0)| 00:00:01 |
16|*  2 |   INDEX RANGE SCAN          | IND_OBJECT_CHAR |     1 |       |     1   (0)| 00:00:01 |
17-----------------------------------------------------------------------------------------------
18
19SQL> SELECT OBJECT_CHAR,OBJECT_NAME FROM IND_TEXT WHERE OBJECT_CHAR=100832;
20
21OBJECT_CHAR          OBJECT_NAME
22-------------------- --------------------
23100832               ORD_ORD_DTL_D
24
25Execution Plan
26----------------------------------------------------------
27Plan hash value: 2154511419
28
29------------------------------------------------------------------------------
30| Id  | Operation         | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
31------------------------------------------------------------------------------
32|   0 | SELECT STATEMENT  |          |     6 |   468 |   143   (3)| 00:00:02 |
33|*  1 |  TABLE ACCESS FULL| IND_TEXT |     6 |   468 |   143   (3)| 00:00:02 |
34------------------------------------------------------------------------------

那么到底查询用number类型存放的数字,查询时不加单引号肯定是走索引的,加上单引号会不会走索引呢,看下面的测试。

01SQL> select OBJECT_NAME,OBJECT_ID from ind_text where OBJECT_ID=100832;
02
03                                                                                                                 OBJECT_NAME          OBJECT_ID
04--------------       -----------
05ORD_ORD_DTL_D        100832
06
07Execution Plan
08----------------------------------------------------------
09Plan hash value: 417862871
10
11---------------------------------------------------------------------------------------------
12| Id  | Operation                   | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
13---------------------------------------------------------------------------------------------
14|   0 | SELECT STATEMENT            |               |     1 |    79 |     2   (0)| 00:00:01 |
15|   1 |  TABLE ACCESS BY INDEX ROWID| IND_TEXT      |     1 |    79 |     2   (0)| 00:00:01 |
16|*  2 |   INDEX RANGE SCAN          | IND_OBJECT_ID |     1 |       |     1   (0)| 00:00:01 |
17---------------------------------------------------------------------------------------------
18
19SQL> select OBJECT_NAME,OBJECT_ID from ind_text where OBJECT_ID='100832';
20
21                                                                                                                 OBJECT_NAME       OBJECT_ID
22--------------    ----------
23ORD_ORD_DTL_D     100832
24
25Execution Plan
26----------------------------------------------------------
27Plan hash value: 417862871
28
29---------------------------------------------------------------------------------------------
30| Id  | Operation                   | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
31---------------------------------------------------------------------------------------------
32|   0 | SELECT STATEMENT            |               |     1 |    79 |     2   (0)| 00:00:01 |
33|   1 |  TABLE ACCESS BY INDEX ROWID| IND_TEXT      |     1 |    79 |     2   (0)| 00:00:01 |
34|*  2 |   INDEX RANGE SCAN          | IND_OBJECT_ID |     1 |       |     1   (0)| 00:00:01 |
35---------------------------------------------------------------------------------------------

可见如果使用number类型存放数字,不论查询时加不加单元号都会走索引的。

总结:如果使用字符类型存放数字,只有在查询时使用单引号将数字引起来才会使用索引;如果是使用数字类型存放数字,查询时不管是否使用单引号,都会走索引。

同分类推荐文章

  1. 使用deepseek进行Oracle恢复,引起重大故障 (2026-06-22 10:56:00)
  2. 接手一个只差临门一脚的数据库恢复 (2026-06-18 00:13:09)
  3. 我做了一个 AI 版的 StarRocks 升级风险扫描工具,直接帮我定位到一个风险 (2026-06-15 01:00:00)

查看更多 数据库 文章 →

建议继续学习

  1. MySQL数据库在实际应用一些方面的介绍 (累计阅读 36,397)
  2. 由浅入深探究mysql索引结构原理、性能分析与优化 (累计阅读 16,519)
  3. 如何查找消耗资源较大的SQL (累计阅读 15,209)
  4. Oracle MTS模式下 进程地址与会话信息 (累计阅读 14,406)
  5. 浅谈MySQL索引背后的数据结构及算法 (累计阅读 11,902)
  6. STRUTS2类型转换错误导致OGNL表达式注入漏洞分析 (累计阅读 10,288)
  7. 其实,文件也可以truncate (累计阅读 8,571)
  8. MariaDB常见问题FAQ (累计阅读 8,341)
  9. SQL vs NoSQL:数据库并发写入性能比拼 (累计阅读 7,999)
  10. Mysql的随机读取 (累计阅读 7,861)