技术群里小伙伴,沟通说一条经常查询的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. 2018-2019-2 20165114《网络对抗技术》Exp7 网络欺诈防范

    Exp7 网络欺诈防范 目录 一.实验内容 二.基础问题回答 (1)通常在什么场景下容易受到DNS spoof攻击 (2)在日常生活工作中如何防范以上两攻击方法 三.实践过程记录 3.1简单应用SET ...

  2. oracle之nvl,nvl2,decode

    oracle sql常用查询nvl,nvl2,decode区别及使用方法 1,NVL( E1, E2) 如果E1为NULL,则NVL函数返回E2的值,否则返回E1的值,如果两个参数都为NULL ,则返 ...

  3. docker-compose EFK查看docker及容器的日志

    上一篇<docker-compose ELK+Filebeat查看docker及容器的日志>已经演示了如何在docker中使用docker-compose创建容器,并将docker中的所有 ...

  4. 微信小程序 scroll-view 填满剩余可用高度

    根据微信小程序 scroll-view 文档所述,scroll-view必须给定一个固定高度.那么如果我们想要让它自动填充剩余高度,该怎么办呢? 前言 在说出我的解决方案之前,先来看一下我的页面设计, ...

  5. Kibana的安装与配置

    Kibana的安装与配置 配置 [root@es01 kibana-5.6.3-linux-x86_64]# egrep -v '^$|^#' config/kibana.yml server.hos ...

  6. 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_18-身份校验-测试

    在顶级域名下配置 网关的地址在上面配置一下 重启nginx 拒绝访问后面的代码都加上 return null 开始测试 换成域名的方式访问 有cookie.但是拿不到header 加上header测试 ...

  7. Dubbo -- 关于 api接口调用不使用强依赖

    首先,我们都知道  Dubbo 调用api 需要提供暴露  接口,   消费端才通过 ZK 可以调用 通常我们都会使用 提供 api  jar包 的方式 使用  这样既方便又快捷 简单 只需要在spr ...

  8. MySQL安装时出现Apply Security Settings错误的解决办法(转)

    最近在学习MySQL时,下载了MySQL5.5版本的安装包,在配置向导的最后的页面却出现了Apply Security Settings的错误.第一次安装时比较顺利,中途卸载了一下,结果第二次安装的时 ...

  9. MySQL建表时添加备注以及查看某一张表的备注信息

    建表的时候对列和表明添加备注: DROP TABLE IF EXISTS test_table; CREATE TABLE test_table ( ID INTEGER AUTO_INCREMENT ...

  10. iOS笔试题02

    1. Difference between shallow copy and deep copy? 1> 浅拷贝:指针(地址)拷贝,不会产生新对象 2> 深拷贝:内容拷贝,会产生新对象 2 ...