在实际使用中,经常会有带in的子查询,如where id in (1,2,3)这样的情况,但是如果很多这样的语句在数据库中出现,将引起数据库的大量硬解析与共享池SQL碎片。所以,在实际应用中,可以采用其他方法,将这些in list给绑定起来。

如果需要绑定in list,首先,需要创建两个类型(type):

针对数据类型的

CREATEOR REPLACE TYPE NUMTABLETYPE as table of number;

针对字符串类型的(每个list的单元大小不要超过1000字节)

createor replace type vartabletype as table of varchar2(1000);

然后创建两个相关的函数

数字列表函数

createor replace function str2numList( p_string in varchar2 ) return numTableType

as

v_str long default p_string || ',';

v_n number;

v_data numTableType := numTableType();

begin

loop

v_n := to_number(instr( v_str, ',' ));

exit when (nvl(v_n,0) = 0);

v_data.extend;

v_data( v_data.count ) := ltrim(rtrim(substr(v_str,1,v_n-1)));

v_str := substr( v_str, v_n+1 );

end loop;

return v_data;

end;

字符列表函数

createor replace function str2varList( p_string in varchar2 ) return VarTableType

as

v_str long default p_string || ',';

v_n varchar2(2000);

v_data VarTableType := VarTableType();

begin

loop

v_n :=instr( v_str, ',' );

exit when (nvl(v_n,0) = 0);

v_data.extend;

v_data( v_data.count ) := ltrim(rtrim(substr(v_str,1,v_n-1)));

v_str := substr( v_str, v_n+1 );

end loop;

return v_data;

end;

创建之后,我们就可以采用如下的方式来使用in list的绑定了。如可以采用如下的三种方案

SELECT/*+ ordered use_nl(a,u) */id, user_id, BITAND(promoted_type,4) busauth

from table(STR2NUMLIST(:bind0)) a,

bmw_users u

where u.user_id = a.column_value

SELECT/*+ leading(a) */id, user_id, BITAND(promoted_type,4) busauth

from bmw_users u where user_id in

(select * from table(STR2NUMLIST(:bind0)) a);

SELECT/*+ index(bmw_users UK_BMW_USERS_USERID) */id, user_id

from bmw_users where user_id in

(SELECT * FROM THE (SELECT CAST(STR2NUMLIST(:bind0) AS NUMTABLETYPE) FROM dual) WHERE rownum<1000)

在如上的方案中,以上语句中的hint提示,是为了稳定执行计划,防止Oracle对in list的错误估计而导致走hash连接。一般建议采用第一种方法,比较简单可靠并且可以指定稳定的计划。但是要求数据库的版本比较高,在老版本中(8i),可能只能采用第三种方法。总的来说,1、2两种方法比3要少6个逻辑读左右。如:

SQL> SELECT /*+ ordered use_nl(a,u) */ id, user_id

2from table(STR2NUMLIST('1,2,3')) a,

3bmw_users u

4*where u.user_id = a.column_value

Execution Plan

----------------------------------------------------------

0SELECT STATEMENT Optimizer=CHOOSE (Cost=3279 Card=8168 Bytes =334888)

10NESTED LOOPS (Cost=3279 Card=8168 Bytes=334888)

21COLLECTION ITERATOR (PICKLER FETCH) OF 'STR2NUMLIST'

31TABLE ACCESS (BY INDEX ROWID) OF 'BMW_USERS' (Cost=1 Card=1 Bytes=39)

43INDEX (UNIQUE SCAN) OF 'UK_BMW_USERS_USERID' (UNIQUE)

Statistics

----------------------------------------------------------

0recursive calls

0db block gets

10consistent gets

0physical reads

0redo size

......

SQL> SELECT/*+ index(bmw_users UK_BMW_USERS_USERID) */ id, user_id

2from bmw_users where user_id in

3*(SELECT * FROM THE (SELECT CAST(STR2NUMLIST('1,2,3') AS NUMTABLETYPE) FROM dual) WHERE rownum<1000)

Execution Plan

----------------------------------------------------------

0SELECT STATEMENT Optimizer=CHOOSE (Cost=430 Card=999 Bytes=51948)

10NESTED LOOPS (Cost=430 Card=999 Bytes=51948)

21VIEW OF 'VW_NSO_1' (Cost=11 Card=999 Bytes=12987)

32SORT (UNIQUE)

43COUNT (STOPKEY)

54COLLECTION ITERATOR (PICKLER FETCH) OF 'STR2NUMLIST'

65TABLE ACCESS (FULL) OF 'DUAL' (Cost=2 Card=82)

71TABLE ACCESS (BY INDEX ROWID) OF 'BMW_USERS' (Cost=1 Card=1 Bytes=39)

87INDEX (UNIQUE SCAN) OF 'UK_BMW_USERS_USERID' (UNIQUE)

Statistics

----------------------------------------------------------

0recursive calls

0db block gets

16consistent gets

0physical reads

0redo size

ORDERED好理解,就是表示根据 from 后面表的顺序join,从左到右,左边的表做驱动表

USE_NL(),先看看

oracle doc怎么说:

In this statement, the USE_NL hint explicitly chooses a

nested loops join with the customers table as the inner table:

SELECT

/*+ ORDERED USE_NL(customers) to get first row faster */

accounts.balance,

customers.last_name, customers.first_name

FROM accounts, customers

WHERE

accounts.customer_id = customers.customer_id;

customers 作为inner

table,也就是说作为被驱动表。驱动表称为outer table。

也就是说use_nl如果只带了一个表名作为参数,则该表为被驱动

表。

如果带了2个以上的参数,oracle 并没有指出 use_nl(a b) 中 哪个是驱动表,所以常使用 ordered 或者

full() 或者 index() 来强化我们的目标

oracle numlist,oracle sql str2numlist numtabletype相关推荐

  1. 监控Oracle性能的SQL

    监控Oracle性能的SQL 1. 监控事例的等待     select event,sum(decode(wait_Time,0,0,1)) "Prev",    sum(dec ...

  2. 利用迁移助手从Oracle迁移到SQL Server

    在实际的项目中,我们常常需要在不同的数据库之前进行迁移,在以前,这可能是和麻烦的事情,但是现在有很多的好的工具可以快速的帮助我们忙成这个目标. 下面我们从来看看如何从Oracle迁移到SQL Serv ...

  3. oracle导入dmp报无效的sql,oracle施用pl/sql导入数据库备份文件dmp导入失败原因

    oracle使用pl/sql导入数据库备份文件dmp导入失败原因 利用PL/SQL导入数据库备份失败: Tools→Import →Tables Import Executable选择导入工具路径 D ...

  4. 判断题:oracle自带的sql语言环境是pl/sql,Oracle之PL/SQL学习笔记之数据类型(三)

    Oracle之PL/SQL学习笔记之数据类型(三) 所有的编程语言中变量是使用最频繁的.PL/SQL作为一个面向过程的数据库编程语言同样少不了变量,利用变量可以把PL/SQL块需要的参数传递进来,做到 ...

  5. 使用navicat premium将数据库从Oracle迁移到SQL Server,或从Oracle迁移到MySQL

    有时候我们有迁移数据库的需求,例如从Oracle迁移到SQL Server,或者从MySQL迁移到Oracle. 很多江湖好汉一时不知如何手工操作,所幸的是Navicat提供了迁移的自动化操作界面. ...

  6. Oracle的PL/SQL编程前奏之基础技能实战一(匿名子程序)

    Oracle的PL/SQL编程之基础技能实战一 一>基础代码检查检查以bm_开头的系统初始化编码表是否有空值.与业务系统相关的编码项不能存在空值,会导致系统业务无法办理.为初始化数据表.在做测试 ...

  7. oracle怎么设置sql每隔一段时间执行一次_Oracle大规模数据快速导出文本文件

    哈喽,前几久,和大家分享过如何把文本数据快速导入数据库(点击即可打开),今天再和大家分享一个小技能,将Oracle数据库中的数据按照指定分割符.指定字段导出至文本文件. 首先来张图,看看导出的数据是什 ...

  8. 【oracle】oracle经典sql,exception,database link纠错

    [oracle]oracle经典sql,exception,database link纠错 1111-01 oracle经典sql,exception,database link纠错 1.给表tabl ...

  9. Oracle临时表和SQL Server临时表的不同点对比

    文章来源:http://www.codesky.net/article/201109/141401.html 1.简介 Oracle数据库除了可以保存永久表外,还可以建立临时表temporary ta ...

最新文章

  1. 文字描边_学会这种描边效果,你的PPT也能这么好看
  2. php转译html,使用php转义输出HTML到JavaScript
  3. 音视频播放、录音、拍照
  4. 谷歌浏览器登录不了账号_谷歌浏览器使用分享(可谷歌账号登录)之谷歌账号登录...
  5. 树形DP(简单题)(Y HDU4705)
  6. 服务器来电后自动开机|xfs文进系统备份恢复linux下误删除的文件
  7. POJ 3264 -----RMQ问题
  8. 安卓控件显示等宽字体的办法
  9. cad老是弹出命令中发生异常_CAD为什么会异常退出?遇到CAD异常退出怎么办-百度经验...
  10. QT软件ICON图标在线制作
  11. 家庭和睦、人生平淡也是一种成功
  12. 【ubuntu】解决 Certificate verification failed: The certificate is NOT trusted
  13. java 打印jpg、pdf、word
  14. pinyin4j:拼音与汉字的转换实例
  15. C语言中的void和void*的定义及用法
  16. 2018,ANG发展峰会惊喜来袭
  17. 基于HTML电商购物项目的设计与实现——html+css+javascript+jquery+bootstarp响应式图书商城
  18. 定点补码运算c语言,单选(3分) 下列关于补码定点运算的描述中,错误的是( )...
  19. 大学生学计算机打字速度,小学生计算机打字速度研究报告
  20. 线性表的链式存储结构以及单链表的插入和删除原理实现

热门文章

  1. 【报告分享】中国“新基建”发展研究报告.pdf(附下载链接)
  2. Make GNN Great Again: GNN 上的预训练和自监督学习
  3. 自然语言处理之TF-IDF
  4. # 异运算_一年级数学:3000道20内纯进、退位口算题,每天100道日新又月异
  5. 使用python排序_Python排序
  6. 什么是智慧仓储化管理系统?
  7. 平台卖家要不要做独立站?
  8. linux实现单机qq_Linux后台服务器开发——Linux下进程间通信的方式有哪些?
  9. 吴恩达深度学习之四《卷积神经网络》学习笔记
  10. 集成学习——XGBoost原理理解