问题描述
嗨,
我有以下sql语句:
APPLICATION_NUMBER是一个VARCHAR字段,并且有一个索引。
当我使用varchar2绑定变量运行查询时,使用索引,并且查询运行速度非常快:
但是,如果绑定变量类型是数字,则查询非常慢 (如预期的那样,它不使用索引,而是运行FTS):
我试图强制查询使用索引 (使用提示),但没有成功。
因为我不能改变应用程序的逻辑,也不能创建基于函数的索引 -- 有没有办法影响优化使用索引?如果我运行的查询条件略有更改 (C.APPLICATION_NUMBER = TO_CHAR (:b1)),它将使用索引并返回正确的值。不过,正如我提到的,我不能改变应用程序代码。
我有以下sql语句:
SELECT C.APPLICATION_NUMBER, D.AGREEMENT_TYPE, C.SUPPLIER_REFERENCE FROM APPLICATION_DATA D, APPLICATION C WHERE C.APPLICATION_NUMBER =:b1 AND D.APPLICATION_ID = C.APPLICATION_ID;复制
APPLICATION_NUMBER是一个VARCHAR字段,并且有一个索引。
当我使用varchar2绑定变量运行查询时,使用索引,并且查询运行速度非常快:
-------------------------------------------------------------------------------------------- | Id | Operation | Name | Cost (%CPU)| Time | -------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 7 (100)| | | 1 | NESTED LOOPS | | 7 (0)| 00:00:01 | | 2 | NESTED LOOPS | | 7 (0)| 00:00:01 | | 3 | TABLE ACCESS BY INDEX ROWID BATCHED| APPLICATION | 5 (0)| 00:00:01 | |* 4 | INDEX RANGE SCAN | APP_APPNUMBER_IDX | 3 (0)| 00:00:01 | |* 5 | INDEX UNIQUE SCAN | APPLICATION_DATA_PK | 1 (0)| 00:00:01 | | 6 | TABLE ACCESS BY INDEX ROWID | APPLICATION_DATA | 2 (0)| 00:00:01 | --------------------------------------------------------------------------------------------复制
但是,如果绑定变量类型是数字,则查询非常慢 (如预期的那样,它不使用索引,而是运行FTS):
----------------------------------------------------------------------------------- | Id | Operation | Name | Cost (%CPU)| Time | ----------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 107K(100)| | | 1 | NESTED LOOPS | | 107K (1)| 00:00:05 | | 2 | NESTED LOOPS | | 107K (1)| 00:00:05 | |* 3 | TABLE ACCESS FULL | APPLICATION | 107K (1)| 00:00:05 | |* 4 | INDEX UNIQUE SCAN | APPLICATION_DATA_PK | 1 (0)| 00:00:01 | | 5 | TABLE ACCESS BY INDEX ROWID| APPLICATION_DATA | 2 (0)| 00:00:01 | -----------------------------------------------------------------------------------复制
我试图强制查询使用索引 (使用提示),但没有成功。
因为我不能改变应用程序的逻辑,也不能创建基于函数的索引 -- 有没有办法影响优化使用索引?如果我运行的查询条件略有更改 (C.APPLICATION_NUMBER = TO_CHAR (:b1)),它将使用索引并返回正确的值。不过,正如我提到的,我不能改变应用程序代码。
专家解答
我很好奇
“并且无法创建基于函数的索引”
为什么不呢?
这似乎是合乎逻辑的答案,不是吗?
“并且无法创建基于函数的索引”
为什么不呢?
这似乎是合乎逻辑的答案,不是吗?
SQL> create table t as 2 select distinct object_type from dba_objects; Table created. SQL> create table t1 as 2 select object_id, to_char(data_object_id) char_col, created, owner, object_type, object_name 3 from dba_objects; Table created. SQL> create index T1_IX on t1 ( char_col); Index created. SQL> SQL> variable num number SQL> variable str varchar2(30); SQL> SQL> exec :num := 12345; PL/SQL procedure successfully completed. SQL> exec :str := '12345'; PL/SQL procedure successfully completed. SQL> SQL> SQL> select count(*) from t, t1 where t1.object_type = t.object_type and char_col = :str; COUNT(*) ---------- 0 1 row selected. SQL> SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST')); PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------------------------------------------------------------- SQL_ID 814t1hjgz5da3, child number 0 ------------------------------------- select count(*) from t, t1 where t1.object_type = t.object_type and char_col = :str Plan hash value: 704178638 ------------------------------------------------------------------------------------------- | Id | Operation | Name | E-Rows | OMem | 1Mem | Used-Mem | ------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | | | 1 | SORT AGGREGATE | | 1 | | | | |* 2 | HASH JOIN | | 1 | 1538K| 1538K| 485K (0)| | 3 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 1 | | | | |* 4 | INDEX RANGE SCAN | T1_IX | 1 | | | | | 5 | TABLE ACCESS FULL | T | 46 | | | | ------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("T1"."OBJECT_TYPE"="T"."OBJECT_TYPE") 4 - access("CHAR_COL"=:STR) SQL> select count(*) from t, t1 where t1.object_type = t.object_type and char_col = :num; COUNT(*) ---------- 0 1 row selected. SQL> SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST')); PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------------------------------------------------------------- SQL_ID f4xx6t3h8gda9, child number 0 ------------------------------------- select count(*) from t, t1 where t1.object_type = t.object_type and char_col = :num Plan hash value: 949044725 ------------------------------------------------------------------------ | Id | Operation | Name | E-Rows | OMem | 1Mem | Used-Mem | ------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | | | | | | 1 | SORT AGGREGATE | | 1 | | | | |* 2 | HASH JOIN | | 1 | 1538K| 1538K| 494K (0)| |* 3 | TABLE ACCESS FULL| T1 | 1 | | | | | 4 | TABLE ACCESS FULL| T | 46 | | | | ------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("T1"."OBJECT_TYPE"="T"."OBJECT_TYPE") 3 - filter(TO_NUMBER("CHAR_COL")=:NUM) SQL> create index t1_ix2 on t1 ( to_number(char_col)) ; Index created. SQL> SQL> select count(*) from t, t1 where t1.object_type = t.object_type and char_col = :num; COUNT(*) ---------- 0 1 row selected. SQL> SQL> select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST')); PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------------------------------------------------------------- SQL_ID f4xx6t3h8gda9, child number 0 ------------------------------------- select count(*) from t, t1 where t1.object_type = t.object_type and char_col = :num Plan hash value: 3299206697 -------------------------------------------------------------------------------------------- | Id | Operation | Name | E-Rows | OMem | 1Mem | Used-Mem | -------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | | | | 1 | SORT AGGREGATE | | 1 | | | | |* 2 | HASH JOIN | | 732 | 1856K| 1856K| 1595K (0)| | 3 | TABLE ACCESS FULL | T | 46 | | | | | 4 | TABLE ACCESS BY INDEX ROWID BATCHED| T1 | 732 | | | | |* 5 | INDEX RANGE SCAN | T1_IX2 | 293 | | | | -------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("T1"."OBJECT_TYPE"="T"."OBJECT_TYPE") 5 - access("T1"."SYS_NC00007$"=:NUM)复制
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
【纯干货】Oracle 19C RU 19.27 发布,如何快速升级和安装?
Lucifer三思而后行
652次阅读
2025-04-18 14:18:38
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
624次阅读
2025-04-15 17:24:06
Oracle数据库一键巡检并生成HTML结果,免费脚本速来下载!
陈举超
527次阅读
2025-04-20 10:07:02
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
522次阅读
2025-04-08 09:12:48
【ORACLE】记录一些ORACLE的merge into语句的BUG
DarkAthena
479次阅读
2025-04-22 00:20:37
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
475次阅读
2025-04-17 17:02:24
Oracle 19c RAC更换IP实战,运维必看!
szrsu
455次阅读
2025-04-08 23:57:08
一页概览:Oracle GoldenGate
甲骨文云技术
454次阅读
2025-04-30 12:17:56
【ORACLE】你以为的真的是你以为的么?--ORA-38104: Columns referenced in the ON Clause cannot be updated
DarkAthena
449次阅读
2025-04-22 00:13:51
火焰图--分析复杂SQL执行计划的利器
听见风的声音
401次阅读
2025-04-17 09:30:30