oracle查询转换_inlist转换
oracle的optimizer会对一些sql语句进行查询转换,比如:
- 合并视图
- 子查询非嵌套化
- inlist转换
下面讲讲遇到的in list转化优化的案例:
create table test(
col1 varchar2(12)
col2 number
ext varchar2(4000)
); create index test_ind on test(user_id, col2);
create sequence seq_test cache 200;
第一步:准备一些测试数据(10个线程随机的插入数据):
#!/bin/sh
for((i=1;i<=$1;i++))
do
/home/oracle/insert.sh &
done
#######################################################
#!/bin/sh
. /home/oracle/.bash_profile
sqlplus -S /nolog<<EOF
conn test/ali88
declare
type arraylist is table of varchar2(20 byte);
arr_user arraylist;
ran number;
begin
arr_user := arraylist();arr_user.extend(3);arr_user(1):='xpchild001';
arr_user(2):='xpchild002';arr_user(3):='xpchild003';
ran :=dbms_random.value(1,3);
while(1>0) loop
insert into test(col1,col2,ext)values(arr_user(ran),seq_test.nextval,dbms_random.string('|', 300));
commit;
DBMS_LOCK.SLEEP(0.05);
end loop;
end;
/
EOF
下面看这个语句的执行计划:
delete from test t where col1 =:1 and col2 in
( :2 , :3 , :4 , :5 , :6 , :7 , :8 , :9 , :10 , :11 , :12 , :13 , :14 , :15 , :16 , :17 , :18 , :19 , :20 , :21); --------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 948 | 5 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| test | 4 | 948 | 5 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | test_ind | 4 | | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("col1"=:1)
filter("col2"=TO_NUMBER(:2) OR "col2"=TO_NUMBER(:3) OR
.........
"col2"=TO_NUMBER(:21))
分析:对于test_ind(col1,col2)这样的组合索引,oracle的优化器使用了access+filter的扫描方式,而对于热点表,或者col1存在大量记录的时候,
这样的扫描会从col1找到最小的col2,顺着leaf节点的链表,找到col2的最大值的区间里,进行filter,看下autotrace后的结果:
Statistics
----------------------------------------------------------
12389 consistent gets
20 rows
这里扫描了col1=:1前导列的所有leaf块,所以尽管只有20条记录,却有12389的逻辑读。
下面对这个sql进行inlist的查询转换:
ops$admin@orcl>alter session set optimizer_index_caching=100; delete /*+ use_concat*/from test t where col1 =:1 and col2 in
( :2 , :3 , :4 , :5 , :6 , :7 , :8 , :9 , :10 , :11 , :12 , :13 , :14 , :15 , :16 , :17 , :18 , :19 , :20 , :21); ---------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 948 | 3 (0)| 00:00:01 |
| 1 | INLIST ITERATOR | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| test | 4 | 948 | 3 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | test_ind | 4 | | 0 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("col1"=:1 AND ("col2"=TO_NUMBER(:2) OR "col2"=TO_NUMBER(:3) OR
"col2"=TO_NUMBER(:4) OR "col2"=TO_NUMBER(:5) OR "col2"=TO_NUMBER(:6) OR
......
/*+
BEGIN_OUTLINE_DATA
NUM_INDEX_KEYS(@"DEL$1" "T"@"DEL$1" "test_ind" 2)
INDEX(@"DEL$1" "T"@"DEL$1" ("test"."col1"
"test"."col2"))
OUTLINE_LEAF(@"DEL$1")
ALL_ROWS
OPT_PARAM('optimizer_index_caching' 100)
OPT_PARAM('_gby_hash_aggregation_enabled' 'false')
OPT_PARAM('_optim_peek_user_binds' 'false')
OPT_PARAM('_index_join_enabled' 'false')
OPT_PARAM('query_rewrite_enabled' 'false')
OPTIMIZER_FEATURES_ENABLE('10.2.0.4')
IGNORE_OPTIM_EMBEDDED_HINTS
END_OUTLINE_DATA
*/
注意:oracle的优化器会对in 列表的查询转换为or的查询,使用use_concat的hint提示,使oracle可以把or的操作转化为concatenate的union all操作。
但是这里如果想要转化为inlist的eterator操作,必须还要调整optimizer_index_caching,可以在system或者session级别,optimizer_index_caching的值的范围
是0到100,表示的是百分比,这个参数影响oracle优化器在选择index时的cost计算,这里设置成100,表示扫描过的root,branch节点块都cache在buffer里,所以每次
iterate从root到branch再到leaf节点时,oracle优化器认为cost会比较小,倾向于使用inlist iterator。
看一下autotrace后的结果:
Statistics
----------------------------------------------------------
81 consistent gets
20 rows
即每条记录平均三个逻辑读,从root->branch->leaf->table block。
如果在生产环境中可以使用profile来固定上面的执行计划,这样不用更改任何的代码逻辑:
declare
v_hints sys.sqlprof_attr;
sql_fulltext clob;
begin
select SQL_FULLTEXT
into sql_fulltext
from v$sqlarea
where sql_id = 'xxxxxx';
v_hints := sys.sqlprof_attr('NUM_INDEX_KEYS(@"DEL$1" "T"@"DEL$1" "test_ind" 2)',
'INDEX(@"DEL$1" "T"@"DEL$1" ("test"."col1"',
'"test"."col2"))',
'OUTLINE_LEAF(@"DEL$1")',
'ALL_ROWS',
'OPT_PARAM(''optimizer_index_caching'' 100)');
dbms_sqltune.import_sql_profile(sql_fulltext,
v_hints,
'test',
force_match => true);
end;
/
oracle查询转换_inlist转换的更多相关文章
- Oracle中使用游标转换数据表中指定字段内容格式(拼音转数字)
应用场景:将数据表TB_USER中字段NNDP的内容中为[sannanyinv]转换为[3男1女] 主要脚本:一个游标脚本+分割字符串函数+拼音转数字脚本 操作步骤如下: 1.创建类型 create ...
- ORACLE常用数值函数、转换函数、字符串函数介绍
ORACLE常用数值函数.转换函数.字符串函数介绍. 数值函数: abs(m) m的绝对值 mod(m,n) m被n除后的余数 power(m,n) m的n次方 round(m[,n]) m四舍五入至 ...
- sql server 导出的datetime结果 CAST(0x00009E0E0095524F AS DateTime) 如何向mysql,oracle等数据库进行转换
1. 处理 sql server 导出的 datetime 类型的字段 在进行sql server向mysql等其他数据进行迁移数据时,会发现使用sql server导出的datetime类型的结果是 ...
- hibernate查询部分字段转换成实体bean
//hibernate查询部分字段转换成实体bean /** * 查询线路信息 */ @Override public List<Line> getSimpleLineListByTj(M ...
- 怎么将oracle的sql文件转换成mysql的sql文件
怎么将sql文件导入PowerDesigner中的方法(将oracle的sql文件转换成mysql的sql文件)呢? 怎么将xx.sql文件的数据库结构导入powerdesigner 的方法呢? 现讲 ...
- LINQ查询表达式详解(2)——查询表达式的转换
简介 C#在执行LINQ查询表达式的时候,并不会指定其执行语义,而是将查询表达式转换为遵循查询表达式模式的方法的调用.具体而言,查询表达式将转换为以下名称的调用:Where.Select.Select ...
- 45 个非常有用的 Oracle 查询语句
这里我们介绍的是 40+ 个非常有用的 Oracle 查询语句,主要涵盖了日期操作,获取服务器信息,获取执行状态,计算数据库大小等等方面的查询.这些是所有 Oracle 开发者都必备的技能,所以快 ...
- 40多个非常有用的Oracle 查询语句
给大家介绍是40多个非常有用的Oracle 查询语句,主要涵盖了日期操作,获取服务器信息,获取执行状态,计算数据库大小等等方面的查询.这些是所有Oracle 开发者都必备的技能,所以快快收藏吧! 日期 ...
- 45个非常有用的 Oracle 查询语句小结
45个非常有用的 Oracle 查询语句小结 这里我们介绍的是 40+ 个非常有用的 Oracle 查询语句,主要涵盖了日期操作,获取服务器信息,获取执行状态,计算数据库大小等等方面的查询.这些是所有 ...
随机推荐
- Servlet单实例多线程模式
http://kakajw.iteye.com/blog/920839 前言:Servlet/JSP技术和ASP.PHP等相比,由于其多线程运行而具有很高的执行效率.由于Servlet/JSP默认是以 ...
- jsp与Action值得对应
例如:Action中有一个全局对象dictionary,对象有种A,B,C三个属性. 1.通过后台将Action中的值传到jsp,需要el表达式. 页面取到A的值 <input name=&qu ...
- javascript面向对象程序设计系列(一)---创建对象
javascript是一种基于对象的语言,但它没有类的概念,所以又和实际面向对象的语言有区别,面向对象是javascript中的难点之一.现在就我所理解的总结一下,便于以后复习: 一.创建对象 1.创 ...
- requirejs源码
require.js /** vim: et:ts=4:sw=4:sts=4 * @license RequireJS 2.1.11 Copyright (c) 2010-2014, The Dojo ...
- 01_JavaMail_04_带附件邮件的发送
[工程截图] [代码实例] package com.Higgin.mail.demo; import java.io.File; import java.util.Properties; import ...
- ubuntu 13.10自定义启动顺序
添加PPA sudo add-apt-repository ppa:danielrichter2007/grub-customizer sudo apt-get update sudo apt-get ...
- 九度OJ 1086 最小花费--动态规划
题目地址:http://ac.jobdu.com/problem.php?pid=1086 题目描述: 在某条线路上有N个火车站,有三种距离的路程,L1,L2,L3,对应的价格为C1,C2,C3.其对 ...
- IIS配置及防黑
安装IIS.部署网站(发布或者拷贝都可以).修改连接字符串,compilation设为false,删掉cs代码 上传文件夹不给执行权限: 在iis管理器中找到上传文件夹,选择属性--执行权限,设置为“ ...
- Java并发编程二三事
Java并发编程二三事 转自我的Github 近日重新翻了一下<Java Concurrency in Practice>故以此文记之. 我觉得Java的并发可以从下面三个点去理解: * ...
- C语言中输入输出格式控制
1.C语言中,非零值为真,真用1表示:零值为假,假用0表示. 2.转义字符参考: \a 蜂鸣,响铃 \b 回退:向后退一格 \f 换页 \n 换行 \r 回车,光标到本行行首 \t 水平制表 \v 垂 ...