隐式转换不走索引的问题,给看看~!

[复制链接]
查看11 | 回复9 | 2013-2-25 14:51:24 | 显示全部楼层 |阅读模式
隐式转换时,不会走索引。为什么 varchar2--> number,有隐式转换; number--->varchar2,怎么就没有隐式转换呢?
SQL> drop table test purge;
SQL> create table test(id varchar2(100),name varchar2(100));
SQL> INSERT INTO test
2(id, NAME)
3SELECT to_char(rownum) AS id, 'name_' || rownum AS NAME
4 FROM dual
5CONNECT BY rownumcreate index ind_test on test (id);
SQL> ALTER system flush shared_pool;
SQL> ALTER system flush BUFFER_CACHE;
SQL> set autotrace traceonly;
SQL> set timing on;
SQL> select * from test where id=1; --这个语句不走索引,能理解,因为有隐式转换。
已用时间:00: 00: 00.17
执行计划
----------------------------------------------------------
Plan hash value: 1357081020
--------------------------------------------------------------------------
| Id| Operation | Name | Rows| Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT|| 4 | 416 | 104 (2)| 00:00:02 |
|*1 |TABLE ACCESS FULL| TEST | 4 | 416 | 104 (2)| 00:00:02 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_NUMBER("ID")=1)
Note
-----
- dynamic sampling used for this statement (level=2)
- SQL plan baseline "SQL_PLAN_9f0t61rapfyzd97bbe3d0" used for this statement
SQL> set autotrace off;
SQL> set timing off;

SQL> drop table test purge;
SQL> create table test(id number,name varchar2(100));
SQL> INSERT INTO test
2(id, NAME)
3SELECT rownum AS id, 'name_' || rownum AS NAME
4 FROM dual
5CONNECT BY rownumcreate index ind_test on test (id);
SQL>
SQL> ALTER system flush shared_pool;
SQL> ALTER system flush BUFFER_CACHE;
SQL> set autotrace traceonly;
SQL> set timing on;
SQL> select * from test where id='1';--不明白这个语句,怎么会走索引呢?id类型是number,我给的是字符,应该有转换,不走索引才对啊?
已用时间:00: 00: 00.06
执行计划
----------------------------------------------------------
Plan hash value: 3856466897
----------------------------------------------------------------------------------------
| Id| Operation
| Name | Rows| Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT
|
| 1 |65 | 2 (0)| 00:00:01 |
| 1 |TABLE ACCESS BY INDEX ROWID| TEST | 1 |65 | 2 (0)| 00:00:01 |
|*2 | INDEX RANGE SCAN
| IND_TEST | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=1)
Note
-----
- dynamic sampling used for this statement (level=2)
- SQL plan baseline "SQL_PLAN_bdcx4n8hmwgbdb8b4d7d8" used for this statement
SQL> set autotrace off;
SQL> set timing off;
SQL> spool off;


回复

使用道具 举报

千问 | 2013-2-25 14:51:24 | 显示全部楼层
不是很明显么,number 和char比较,会把char to_number,第二个测试,会把'1' to_number, id列上没有转换发生,看计划!
回复

使用道具 举报

千问 | 2013-2-25 14:51:24 | 显示全部楼层
我能想到的是,当发生隐式转换时,会将字符串转换成NUMBER类型。
所以应该是select * from test where id=to_number('1'); 这样会走索引扫描。
坐等大神。
回复

使用道具 举报

千问 | 2013-2-25 14:51:24 | 显示全部楼层
absent_young 发表于 2013-2-5 16:31
我能想到的是,当发生隐式转换时,会将字符串转换成NUMBER类型。
所以应该是select * from test where id= ...

不需要加to_number就能走索引,因为你那样写id肯定是数值类型,如果是字符串类型,也走不了索引
字符串和数值类型比较,会将字符串转为数值类型
字符串与日期表,会转为日期
回复

使用道具 举报

千问 | 2013-2-25 14:51:24 | 显示全部楼层
详细的你看看sql reference上的type conversion章节,类型之间很多是可以相互转换的
回复

使用道具 举报

千问 | 2013-2-25 14:51:24 | 显示全部楼层
udfrog 发表于 2013-2-5 16:30
不是很明显么,number 和char比较,会把char to_number,第二个测试,会把'1' to_number, id列上没有转换发生 ...

谢谢,我理解的是,=左边都应该转换到=右边的类型。
理解跑偏了。


回复

使用道具 举报

千问 | 2013-2-25 14:51:24 | 显示全部楼层
dingjun123 发表于 2013-2-5 16:40
不需要加to_number就能走索引,因为你那样写id肯定是数值类型,如果是字符串类型,也走不了索引
字符串 ...

谢谢~!
对基础知识理解不深刻,遇到问题反映不过来,哎...
回复

使用道具 举报

千问 | 2013-2-25 14:51:24 | 显示全部楼层
http://www.itpub.net/forum.php?mod=viewthread&tid=1303566
看这个,很早之前写的
回复

使用道具 举报

千问 | 2013-2-25 14:51:24 | 显示全部楼层
写条件的时候严格按照数据类型来写, 那隐式数据类型转换不就可以避免了吗
回复

使用道具 举报

千问 | 2013-2-25 14:51:24 | 显示全部楼层
bell6248 发表于 2013-2-5 17:03
写条件的时候严格按照数据类型来写, 那隐式数据类型转换不就可以避免了吗

我想测下,索引列有隐式转换时,不走索引的情况。就发现了这个问题,
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行