技术群里小伙伴,沟通说一条经常查询的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. git补充(关于pull request)转自知乎

    当你想更正别人仓库里的错误时,要走一个流程: 1先 fork 别人的仓库,相当于拷贝一份,不会有人直接让你修改原仓库的 2.clone 到本地分支,做一些 bug fix 3.发起 pull requ ...

  2. Java 面向对象(十二)

    泛型 什么是泛型 泛型:广泛通用的类型 一开始还不确定是什么类型,在使用的时候,才能确定是什么类型 (1)在开始定义的时候,留一个插口 (2)在创建对象的时候,再去插入对应的类型 泛型也可以理解为&q ...

  3. maven手动将jar包导入到本地仓库(支持多个仓库选择)

    正常我们在用maven搭建项目时,我们只需要将项目所需要的依赖配置到maven的配置文件pom.xml中即可,maven就可以去网上将jar包下载到配置的本地仓库中去.所以一般情况下我们是不需要手动安 ...

  4. 在从myql服务器上 取消主从关系和重新构建主从关系

    取消主从关系 mysql -uroot -p mysql>show slave status\G; 查看主库是否为之前的ip mysql>change master to master_h ...

  5. 【Oracle】创建用户及设定权限

    ; grant create session to ufo; grant create tablespace to ufo; grant create table to ufo; grant drop ...

  6. 到达型01背包---P1877 [HAOI2012]音量调节

    P1877 [HAOI2012]音量调节 题解 solution 1 普通dfs  60pt dfs 暴搜,pos 记录当前到了第几首歌,level 记录当前的音量 一个小剪枝 由于每换一首歌都要调节 ...

  7. 如何十倍提高你的webpack构建效率

    前言 http://jafeney.com/2016/07/10/2016-07-10-webpack/     webpack 是个好东西,和 NPM 搭配起来使用管理模块实在非常方便.而 Babe ...

  8. List三个子类的特点

    List的三个子类的特点 ArrayList: 底层数据结构是数组,查询快,增删慢. 线程不安全,效率高. Vector: 底层数据结构是数组,查询快,增删慢. 线程安全,效率低. Vector相对A ...

  9. 《最长的一帧》 osg3.4 osgViewer::View::init() osgViewer::Viewer::getContexts()

    开始:osgViewer/ViewerBase.cpp   389行,startThreading()函数,启动线程   void ViewerBase::startThreading() { if ...

  10. osg::Camera example

    #ifdef _WIN32 #include <Windows.h> #endif // _WIN32 #include<iostream> #include <osgV ...