技术群里小伙伴,沟通说一条经常查询的SQL缓慢,单表SQL一个列作为条件,列是int数值类型,索引类型默认创建。

一.SQL文本
substr函数索引创建测试
select *from(select substr(nm,,) nm1 from bbm2019) where nm1 in ('')
需求,将上述SQL执行速度加快,目的是走索引。
创建测试表
SQL>create table tt as select * from dba_objects;
SQL> desc tt
 OBJECT_ID                           NUMBER
二.优化思路
2.1 通过修改SQL文本方式
调整前
SQL> select * from (select substr(object_id,,) cc from tt) t where t.cc in ('');
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| | SELECT STATEMENT | | | | ()| :: |
|* | TABLE ACCESS FULL| TT | | | ()| :: |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
- filter(SUBSTR(TO_CHAR("OBJECT_ID"),,)='')
调整后,使用单行SQL查询,不使用子查询
SQL> select substr(object_id,,) from tt where substr(object_id,,) in ('');
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| | SELECT STATEMENT | | | | ()| :: |
|* | TABLE ACCESS FULL| TT | | | ()| :: |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
- filter(SUBSTR(TO_CHAR("OBJECT_ID"),,)='')
无效,SQL还是一次全表扫描,只是测试使用。 2.2 调整索引为字符格式,SQL访问使用%模糊匹配
select substr(nm,,) nm1 lrrq from bbm2019 where nm1in like '55552389655808973%';
SQL> create index tt_obje_ind on tt(object_id);
SQL> set autotrace on
SQL>select object_id from tt where object_id like '25599%';
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| | SELECT STATEMENT | | | | ()| :: |
|* | TABLE ACCESS FULL| TT | | | ()| :: |
--------------------------------------------------------------------------
可以发现,当表字段为数值类型,使用like 字符格式访问,是无法获取结果的。
SQL> drop index tt_obje_ind;
SQL> create index tt_obje_ind on tt(to_char(object_id));
SQL> select object_id from tt where object_id like '25599%';
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| | SELECT STATEMENT | | | | ()| :: |
| | TABLE ACCESS BY INDEX ROWID| TT | | | ()| :: |
|* | INDEX RANGE SCAN | TT_OBJE_IND | | | ()| :: |
-------------------------------------------------------------------------------------------
SQL> select object_id from tt where object_id like '2559%';
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| | SELECT STATEMENT | | | | ()| :: |
| | TABLE ACCESS BY INDEX ROWID| TT | | | ()| :: |
|* | INDEX RANGE SCAN | TT_OBJE_IND | | | ()| :: |
-------------------------------------------------------------------------------------------

2 - access(TO_CHAR("OBJECT_ID") LIKE '2559%')
          filter(TO_CHAR("OBJECT_ID") LIKE '2559%')

使用to_char可以将索引存储格式调整为字符类型,where条件使用%进行查询可以走索引快速访问。
SQL> select object_id from tt where object_id='';
SQL> select object_id from tt where object_id in ''; SQL> select substr(object_id,,) from tt where object_id in('');
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| | SELECT STATEMENT | | | | ()| :: |
|* | TABLE ACCESS FULL| TT | | | ()| :: |
--------------------------------------------------------------------------
发现使用in =并未走索引!
   1 - filter("OBJECT_ID"=25599) 可以发现并未显示to_char
此处,第一次发现oracle隐患转换的优先级,可能会影想是否走索引,由于oracle to_number优先级大于to_char因此即使我们写法'xx'字符数值等值查询,
oracle自动转换为数值类型,由于索引为字符类型,因此无法走索引。
SQL> select object_id from tt where to_char(object_id)='25599';  

-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 870 | 23490 | 72 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TT | 870 | 23490 | 72 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TT_OBJE_IND | 348 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

2 - access(TO_CHAR("OBJECT_ID")='25599')

不创建函数索引,直接使用to_char类,查询条件

2.3 创建Substr函数索引
SQL> drop index tt_obje_ind;
SQL> create index tt_obje_ind on tt(substr(object_id,,));
SQL> select substr(object_id,,) from tt where substr(object_id,,) in ('');
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| | SELECT STATEMENT | | | | ()| :: |
|* | INDEX RANGE SCAN| TT_OBJE_IND | | | ()| :: |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
- access(SUBSTR(TO_CHAR("OBJECT_ID"),,)='')
SQL> create index tt_obje_ind on tt(substr(to_char(object_id),,));
SQL> select substr(object_id,,) from tt where substr(object_id,,) in ('');
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| | SELECT STATEMENT | | | | ()| :: |
|* | INDEX RANGE SCAN| TT_OBJE_IND | | | ()| :: |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
- access(SUBSTR(TO_CHAR("OBJECT_ID"),,)='')
创建substr函数索引,oracle自动会to_char转换,可以显示创建索引语法加上 (可不加,规范语法加上最好~)
on tt(substr(to_char(object_id),0,4)); 

substr函数索引创建测试的更多相关文章

  1. oracle的位图索引和函数索引

    1.位图索引 位图索引适用于性别.婚姻状态.行政区等只有几列固定值的类型列,身份证号等就不适合位图索引,位图索引适用于静态数据,频繁更新的字段不适用建立位图索引,因为更新会导致索引块区的变更,还会引起 ...

  2. MYSQL进阶学习笔记五:MySQL函数的创建!(视频序号:进阶_13)

    知识点六:MySQL函数的创建(13) 内置函数: 自定义函数: 首先查看是否已经开启了创建函数的功能: SHOW VARIABLES LIKE ‘%fun%’; 如果变量的值是OFF,那么需要开启 ...

  3. [20180408]那些函数索引适合字段的查询.txt

    [20180408]那些函数索引适合字段的查询.txt --//一般不主张建立函数索引,往往是开发的无知,使用trunc等函数,实际上一些函数也可以用于字段的查询.--//以前零碎的写过一些,放假看了 ...

  4. MySQL 高级 视图 事物 触发器 函数 索引优化

    视图 1.什么是视图 ​ 视图就是通过查询得到一张虚拟表,然后保存下来,下次直接使用即可 2.为什么要用视图 ​ 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何用视图 create view t ...

  5. MySQL函数索引及优化

    很多开发人员在使用MySQL时经常会在部分列上进行函数计算等,导致无法走索引,在数据量大的时候,查询效率低下.针对此种情况本文从MySQL5.7 及MySQL8.0中分别进行不同方式的优化. 1. M ...

  6. Oracle索引梳理系列(六)- Oracle索引种类之函数索引

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  7. MySQL 5.7新特性之Generated Column(函数索引)

    MySQL 5.7引入了Generated Column,这篇文章简单地介绍了Generated Column的使用方法和注意事项,为读者了解MySQL 5.7提供一个快速的.完整的教程.这篇文章围绕 ...

  8. 利用函数索引优化<>

    SQL> select count(*),ID from test_2 group by id; COUNT(*) ID ---------- ---------- 131072 1 11796 ...

  9. SQLServer中间接实现函数索引或者Hash索引

    本文出处:http://www.cnblogs.com/wy123/p/6617700.html SQLServer中没有函数索引,在某些场景下查询的时候要根据字段的某一部分做查询或者经过某种计算之后 ...

随机推荐

  1. cannot load from mysql.proc. the table is probably corrupted 解决办法

    执行以下命令:mysql_upgrade -u root -p 密码 mysql5.5及5.5以上的版本开始,mysql数据库中proc表中的comment字段的列属性已经由char(64)改为tex ...

  2. 制作 ESXI6.7 U盘安装盘并用其安装

    工具 UltraISO   :软碟通官网下载 EXSI镜像文件:http://ddl6.digiboy.ir/vmware/6.7/VMware-VMvisor-Installer-6.7.0-816 ...

  3. 使用Flask构建机器学习模型API

    1. Python环境设置和Flask基础 使用"Anaconda"创建一个虚拟环境.如果你需要在Python中创建你的工作流程,并将依赖项分离出来,或者共享环境设置," ...

  4. 用了pm2之后,如何让console.log('..')出现在控制台

    使用  pm2 log 0 可以查看.当然这个 0 应该是应用的 id

  5. CentOS7系统下GitLab的安装、汉化、修改默认端口、开启发送邮箱

    一.centos7.4 下安装及汉化 =============================================== 2017/11/12_第6次修改                  ...

  6. 阶段5 3.微服务项目【学成在线】_day16 Spring Security Oauth2_20-认证接口开发-接口测试

    测试接口 因为继承了spring  security会拦截这个请求,我们需要写代码 让他对这个认证接口放行 查看代码发现之前已经写过放行的代码了 发现是路径前面少了auth 加断点,测试.申请令牌 r ...

  7. Intellij IDEA 2016.3.4 注册激活--转

    对于Intellij IDEA 2016.3.4  可以填写注册server http://jetbrains.tech 来激活. 参考:https://www.haxotron.com/jetbra ...

  8. VMware15安装Centos7超详细过程

    本篇文章主要介绍了VMware安装Centos7超详细过程(图文),具有一定的参考价值,感兴趣的小伙伴们可以参考一下 1.软硬件准备 软件:推荐使用VMwear15,我用的是VMwear 15 镜像: ...

  9. 波特词干(Porter Streamming)提取算法无代码单纯理解

    最近写东西提到这个算法,要看一下,结果网上都是直接根据代码解释,对于我这种菜鸟在刚开始看一个算法的时候真心不想直接看代码学.奈何都是各种语言的代码,么得办法.先走了一遍,有了大致的了解,翻译成自己的话 ...

  10. php open_basedir的使用与性能分析

    php open_basedir的使用与性能分析 使用方法 <pre>/*限制打开的目录*/ini_set('open_basedir', __DIR__.'/');</pre> ...