`
13594135
  • 浏览: 193054 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Oracle怎么对IN子查询使用绑定变量(转)

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

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

针对数据类型的

CREATE OR REPLACE TYPE NUMTABLETYPE as table of number;

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

create or replace type vartabletype as table of varchar2(1000);

然后创建两个相关的函数

数字列表函数
create or 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;

字符列表函数
create or 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
  2   from table(STR2NUMLIST(’1,2,3′)) a,
  3   bmw_users u
  4*  where u.user_id = a.column_value

Execution Plan
———————————————————-
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=3279 Card=8168 Bytes =334888)
   1    0   NESTED LOOPS (Cost=3279 Card=8168 Bytes=334888)
   2    1     COLLECTION ITERATOR (PICKLER FETCH) OF ‘STR2NUMLIST’
   3    1     TABLE ACCESS (BY INDEX ROWID) OF ‘BMW_USERS’ (Cost=1 Card=1 Bytes=39)
   4    3       INDEX (UNIQUE SCAN) OF ‘UK_BMW_USERS_USERID’ (UNIQUE)

Statistics
———————————————————-
          0  recursive calls
          0  db block gets
         10  consistent gets
          0  physical reads
          0  redo size
……
                               
SQL> SELECT  /*+ index(bmw_users UK_BMW_USERS_USERID) */ id, user_id
  2   from 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
———————————————————-
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=430 Card=999 Bytes=51948)
   1    0   NESTED LOOPS (Cost=430 Card=999 Bytes=51948)
   2    1     VIEW OF ‘VW_NSO_1′ (Cost=11 Card=999 Bytes=12987)
   3    2       SORT (UNIQUE)
   4    3         COUNT (STOPKEY)
   5    4           COLLECTION ITERATOR (PICKLER FETCH) OF ‘STR2NUMLIST’
   6    5             TABLE ACCESS (FULL) OF ‘DUAL’ (Cost=2 Card=82)
   7    1     TABLE ACCESS (BY INDEX ROWID) OF ‘BMW_USERS’ (Cost=1 Card=1 Bytes=39)
   8    7       INDEX (UNIQUE SCAN) OF ‘UK_BMW_USERS_USERID’ (UNIQUE)

Statistics
———————————————————-
          0  recursive calls
          0  db block gets
         16  consistent gets
          0  physical reads
          0  redo size
分享到:
评论

相关推荐

    【oracle】oracle查询优化改写

    4. **绑定变量**:使用绑定变量可以避免SQL硬解析,提高SQL语句的复用性,减少系统资源的消耗。 5. **提示(Hints)**:在SQL查询中添加提示可以指导优化器选择特定的执行计划,但这应谨慎使用,因为过度依赖提示...

    Oracle性能查询包使用

    4. **子查询优化**:子查询可能会导致多次表访问,考虑使用连接(JOIN)或连接重写来替换子查询。 三、性能监控与调优工具 1. **V$视图**:Oracle提供了一系列V$视图,如V$SESSION, V$SQL, V$BUFFER_CACHE等,用于...

    提高Oracle查询效率

    - **使用EXISTS替代IN**:当需要检查子查询结果是否包含主查询中的记录时,EXISTS通常比IN更快,因为它一旦找到匹配就停止。 3. **Oracle工具使用** - **Explain Plan**:Oracle自带的解释计划工具,可以分析SQL...

    oracle连接查询SQL性能测试

    4. **子查询与连接的比较**:在某些情况下,子查询可能比连接更高效,反之亦然。文章可能比较了两者在不同场景下的性能表现。 5. **并行查询**:Oracle支持并行执行查询,这可以在大型数据集上提高性能。不过,过度...

    ORACLE多表查询优化

    开发者可以使用其他查询方式,例如使用子查询或 EXISTS 语句来替代多表连接查询。 6. 优化数据统计 数据统计是数据库性能的关键。开发者可以使用不同的统计方法,例如使用索引、分区表、物化视图等来提高数据统计...

    Oracle 查询优化,个人练习

    6. **绑定变量**:使用绑定变量可以提高重用执行计划的效率,避免因参数化不佳导致的硬解析。 7. **查询重写**:通过数据库的查询重写功能,可以将复杂查询转化为更简单的形式,比如利用物化视图或索引组织表。 8....

    oracle查询优化

    8. **使用绑定变量**:在动态SQL中使用绑定变量可以减少解析开销,因为相同语句只需要解析一次,即使有变化的参数。 9. **分析和维护统计信息**:定期运行ANALYZE命令更新表和索引的统计信息,有助于优化器做出更好...

    oracle 查询优化改写

    4. 减少子查询,尽可能用连接替换子查询,或使用exists和in子句代替not in,因为前者通常效率更高。 三、并行查询 对于大规模数据处理,启用并行查询可以将任务分散到多个处理器上,缩短执行时间。但需注意,过度...

    Oracle查询优化改写技巧与案例.rar

    尽量避免在SQL语句中使用常量,改为使用绑定变量。 6. **减少全表扫描** - 全表扫描对大数据量的表来说非常耗时,利用索引、分区、位图索引等方式减少全表扫描。 7. **优化GROUP BY和HAVING** - 使用索引对GROUP...

    oracle优化报表查询.zip

    这包括但不限于:使用合适的JOIN条件,避免全表扫描,利用索引,减少子查询,以及使用连接(JOIN)替代子查询。 2. **索引策略**:Oracle提供了多种类型的索引,如B树索引、位图索引、函数索引等。选择正确的索引...

    Oracle查询优化改写-技巧与案例

    8. **存储过程和函数优化**:优化存储过程和函数,包括减少调用次数,使用绑定变量,以及避免在过程中进行大事务。 9. **性能监控和诊断**:书中可能还会讲解如何使用Oracle的性能监视工具(如AWR报告、ASH分析),...

    ORACLE培训SQL性能优化.pptx

    在解析阶段,ORACLE 会检查语法、语义和权限,并合并视图定义和子查询。然后,在绑定阶段,ORACLE 会查找绑定变量并赋值。在执行阶段,ORACLE 会应用执行计划并执行必要的 I/O 和排序操作。最后,在提取阶段,ORACLE...

    oracle编程的性能注意点

    此外,避免使用in/exists、not in/not exists子查询,转而采用直接连接的方式也是提高性能的有效手段。这些子查询可能导致全表扫描和多次表访问,尤其是在数据量大的情况下,性能开销显著。例如,使用NOT IN或NOT ...

    Oracle查询优化案例

    5. **使用绑定变量**:避免硬解析,使用绑定变量可以重用执行计划,减少解析开销,尤其在处理大量相似查询时。 6. **减少行处理**:通过限制返回的行数,如使用`FETCH FIRST n ROWS ONLY`或`LIMIT`,可以降低I/O和...

    Oracle数据库中分页查询介绍

    在Oracle数据库中,分页查询是一项...总的来说,实现Oracle数据库中的分页查询需要理解ROWNUM的特性和正确使用子查询或存储过程。通过合理利用这些技术,开发人员可以在保证性能的同时,为用户提供流畅的分页浏览体验。

    Oracle查询优化改写技巧与案例

    1. INNER JOIN通常比子查询和NOT IN更高效,特别是在处理大数据量时。 2. 优先考虑使用ANSI SQL-92标准的JOIN语法,避免嵌套查询和子查询。 案例:`SELECT t1.* FROM table1 t1 WHERE t1.id IN (SELECT t2.id FROM...

    ORACLE查询优化

    4. **子查询优化**:尽可能将子查询转化为连接查询,或者使用关联子查询,减少数据处理的复杂度。 二、查询语句优化 1. **避免全表扫描**:通过WHERE子句准确筛选数据,避免无谓的数据扫描。 2. **限制返回行数**...

    Oracle 10g数据库海量数据分页查询优化.pdf

    例如,可以使用索引、分区表、子查询等技术来优化 SQL 语句。此外,使用游标变量也可以提高查询效率。 cursor variables 游标变量是 Oracle 10g 数据库中的一种特殊变量,可以用来存储查询结果。通过使用游标...

    oracle9i的查询优化

    可以考虑使用连接操作替换子查询,或者利用exists和in子句优化查询结构。 6. **物化视图**:对于固定查询模式,可以创建物化视图来预先计算结果,提供快速的数据访问。但需注意更新维护的成本。 7. **表分区**:大...

    Oracle数据库查询优化分析与研究.pdf

    6. **优化子查询**:减少子查询的使用,或利用关联子查询替代嵌套子查询,提高查询效率。 7. **注意排序和分组操作**:排序和分组操作会消耗大量资源,尽可能利用索引进行排序,避免不必要的全表排序。 8. **监控...

Global site tag (gtag.js) - Google Analytics