技术群里小伙伴,沟通说一条经常查询的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. 面试题小议---BY gremount

    Problem 1:  两个烧杯,一个放糖一个放盐,用勺子舀一勺糖到盐,搅拌均匀,然后舀一勺混合物会放糖的烧杯,问你两个烧杯哪个杂质多? 提示:相同.(1)可以用一个特殊数据计算一下,可以得到两个烧杯 ...

  2. mac电脑如何快速显示桌面及切换应用

    使用mac电脑时,我们习惯打开很多应用,文档等等.如果打开应用非常多,需要操作桌面,却不知如何快速返回桌面和切换应用时,操作就非常不便了,下面简单介绍mac电脑系统如何快速显示桌面及切换应用? 工具/ ...

  3. MAC将根目录文件夹的权限赋给用户

    https://my.oschina.net/liujiest/blog/762004 1.sudu -i进入root模式(需输入密码) 2.chown -R 用户名 /文件夹名 sudo -i Pa ...

  4. Interacted Action-Driven Visual Tracking Algorithm

    文章来源:Attentional Action-Driven Deep Network for Visual Object Tracking   博士论文(2017年8月份完稿) http://s-s ...

  5. php-图片加水印和文字

    //************************** 图片加文字 ************************ $dst_path = '11.jpg';//创建图片的实例$dst = ima ...

  6. 转换为CString

    CString a, b, c;c = a + b; 使用Format方法方便的实现int.float和double等数字类型转换为CString字符串. %c 单个字符 %d 十进制整数(int) ...

  7. LC 375. Guess Number Higher or Lower II

    We are playing the Guess Game. The game is as follows: I pick a number from 1 to n. You have to gues ...

  8. 亲历谷歌 Chrome 浏览器弹窗境外广告的解决方法(图) | 技术乐园

    亲历谷歌 Chrome 浏览器弹窗境外广告的解决方法(图) | 技术乐园 转 https://www.hack520.com/338.html 谷歌的 Chrome 浏览器是我非常喜欢的一款的浏览器, ...

  9. 简易的CRM系统案例之SpringMVC+JSP+MySQL+myBatis框架版本

    主要对上一版DAO框架的替换hibernate变成myBatis 简易的CRM系统案例之SpringMVC+JSP+MySQL+hibernate框架版本 src/mybatis.xml <?x ...

  10. opencv之调用摄像头

    基础知识 # cap.set(propId, value) # 设置视频参数: propId - 设置的视频参数, value - 设置的参数值 # cap.isOpened() 返回 true/fa ...