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 查询语句,主要涵盖了日期操作,获取服务器信息,获取执行状态,计算数据库大小等等方面的查询.这些是所有 ...
随机推荐
- 通过javascript库JQuery实现页面跳转功能代码
通过javascript库JQuery实现页面跳转功能代码的四段代码实例如下. 实例1: 1 2 3 4 $(function(){ var pn = $("#gotopagenum&quo ...
- Hibernate不同DB的日期查询
Java web项目开发,ORM层用的是Hibernate,用HQL语句查询不同数据库时,日期时间比较还是有所区别的. 1.在Mysql数据库时,是这样写的: 上面是个代码拼串截图,翻译一下是这样的: ...
- 增加Swap内存
增加512M Swap内存 #首先先建立一个分区,采用dd命令如下:dd if=/dev/zero of=/home/swap bs=1024 count=524288#(1个block为1K,512 ...
- (poj) 1751 Highways
Description The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has a very poor ...
- jQuery DataTables 插件使用笔记
初始化 在页面中 <!DOCTYPE html> <html> <head> <link rel="stylesheet" type=&q ...
- C#XML创建与节点对象引用
我们在创建xml过程中会遇到不同的级别有相同节点的情况.如下面的xml: <?xml version="1.0" encoding="GBK"> & ...
- C#winform程序安装时自动卸载新版本覆盖旧版本
vs2005为winform程序做的安装包.在以有程序旧版本的机子上用新版本的安装包安装软件时提示 “以经安装该产品的另一个版本.无法继续安装此版本........” 在安装部署项目中设“Remov ...
- C++顺序容器类总结
主要是vector,deque,list,forward_list,array,string 插入方法: 元素访问: 元素删除: 容器赋值: forward_list有很多特殊的方法 毕竟平时forw ...
- SQLite批量插入,修改数据库 zt
SQLiteConnection sqConnection = dataProvider.GetDbConnection(); sqConnection.Open(); SQLiteCommand s ...
- iOS - instancetype
OC是一门正在迅速发展的语言,ARC,object literals ,subscripting ,blocks,Auto Synthesis,让我们看到它惊人的改变.instancetype是cla ...