前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >隐式转换的替代方案不是万能的

隐式转换的替代方案不是万能的

作者头像
bisal
发布2022-03-11 08:55:22
2270
发布2022-03-11 08:55:22
举报

隐式转换相关的历史文章,

隐式转换之前谈的比较多了,这个问题如果单从功能测试上,不一定能发现,但是通过执行计划、静态扫描等,还是能找到一些端倪的,归根结底,还是不规范的设计和开发,导致出现的。

有些隐式转换能通过替代方案解决,例如创建函数索引、将左侧的表达式转换到右侧、更改字段类型、更改变量类型等,但是不是说所有的替代方案在所有场景都适用。

创建测试数据,

代码语言:javascript
复制
SQL> create table test_timestmap_date(c1 date, c2 timestamp);
Table Created.


SQL> insert into test_timestmap_date values(sysdate, systimestamp);
1 row created.


SQL> create index idx_test_timestmap_date_01 on test_timestmap_date(c1);
Index Created.


SQL> commit;
Commit Completed.

我们知道,如果是"where date = date",

代码语言:javascript
复制
SQL> select * from test_timestmap_date where c1=sysdate;
...

会使用到索引,

代码语言:javascript
复制
------------------------------------------------------------------------------------------------------------------
| Id  | Operation                           | Name                       | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                    |                            |       |       |     1 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| TEST_TIMESTMAP_DATE        |     1 |    22 |     1   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN                  | IDX_TEST_TIMESTMAP_DATE_01 |     1 |       |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("C1"=SYSDATE@!)

如果是"where date = timestamp",右值优先级高,可以看到,左值使用了内部函数INTERVAL_FUNCTION,不会用到索引,

代码语言:javascript
复制
SQL> select * from test_timestmap_date where c1=systimestamp;
...


-----------------------------------------------------------------------------------------
| Id  | Operation         | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                     |       |       |     3 (100)|          |
|*  1 |  TABLE ACCESS FULL| TEST_TIMESTMAP_DATE |     1 |    22 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(SYS_EXTRACT_UTC(INTERNAL_FUNCTION("C1"))=SYS_EXTRACT_UTC(SYSTIMESTAMP(6)))

如果是varchar2、number,通常能通过to_number()函数作为方案让其能用到索引,但是针对date、timestamp类型的,to_timestamp()不会起作用。

如下所示,创建一个to_timestamp()的函数索引,强制将date转成timestamp类型,

代码语言:javascript
复制
SQL> create index idx_test_timestmap_date_02 on test_timestmap_date(to_timestamp(c1, 'yyyy-mm-dd hh24:mi:ss'));
Index Created.

但实际执行,仍采用全表扫描,

代码语言:javascript
复制
SQL> select * from test_timestmap_date where c2 = systimestamp;
...


-----------------------------------------------------------------------------------------
| Id  | Operation         | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |                     |       |       |     3 (100)|          |
|*  1 |  TABLE ACCESS FULL| TEST_TIMESTMAP_DATE |     1 |    22 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(SYS_EXTRACT_UTC(INTERNAL_FUNCTION("C2"))=SYS_EXTRACT_UTC(SYSTIMESTAMP(6)))

因此,针对这种场景,只能通过修改代码,将程序中的变量类型从timestamp改成date,或者将数据库中的字段类型从date改成timestamp,不能通过仅仅创建函数索引解决。

还是最开始说的,大多数隐式转换,是可以通过规范设计和开发,在投产前的环节进行规避,否则就只能等着出现问题,然后尝试各种替代方案了寻求解决了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-03-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档