在实际使用中,经常会有带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
分享到:
相关推荐
4. **绑定变量**:使用绑定变量可以避免SQL硬解析,提高SQL语句的复用性,减少系统资源的消耗。 5. **提示(Hints)**:在SQL查询中添加提示可以指导优化器选择特定的执行计划,但这应谨慎使用,因为过度依赖提示...
4. **子查询优化**:子查询可能会导致多次表访问,考虑使用连接(JOIN)或连接重写来替换子查询。 三、性能监控与调优工具 1. **V$视图**:Oracle提供了一系列V$视图,如V$SESSION, V$SQL, V$BUFFER_CACHE等,用于...
- **使用EXISTS替代IN**:当需要检查子查询结果是否包含主查询中的记录时,EXISTS通常比IN更快,因为它一旦找到匹配就停止。 3. **Oracle工具使用** - **Explain Plan**:Oracle自带的解释计划工具,可以分析SQL...
4. **子查询与连接的比较**:在某些情况下,子查询可能比连接更高效,反之亦然。文章可能比较了两者在不同场景下的性能表现。 5. **并行查询**:Oracle支持并行执行查询,这可以在大型数据集上提高性能。不过,过度...
开发者可以使用其他查询方式,例如使用子查询或 EXISTS 语句来替代多表连接查询。 6. 优化数据统计 数据统计是数据库性能的关键。开发者可以使用不同的统计方法,例如使用索引、分区表、物化视图等来提高数据统计...
6. **绑定变量**:使用绑定变量可以提高重用执行计划的效率,避免因参数化不佳导致的硬解析。 7. **查询重写**:通过数据库的查询重写功能,可以将复杂查询转化为更简单的形式,比如利用物化视图或索引组织表。 8....
8. **使用绑定变量**:在动态SQL中使用绑定变量可以减少解析开销,因为相同语句只需要解析一次,即使有变化的参数。 9. **分析和维护统计信息**:定期运行ANALYZE命令更新表和索引的统计信息,有助于优化器做出更好...
4. 减少子查询,尽可能用连接替换子查询,或使用exists和in子句代替not in,因为前者通常效率更高。 三、并行查询 对于大规模数据处理,启用并行查询可以将任务分散到多个处理器上,缩短执行时间。但需注意,过度...
尽量避免在SQL语句中使用常量,改为使用绑定变量。 6. **减少全表扫描** - 全表扫描对大数据量的表来说非常耗时,利用索引、分区、位图索引等方式减少全表扫描。 7. **优化GROUP BY和HAVING** - 使用索引对GROUP...
这包括但不限于:使用合适的JOIN条件,避免全表扫描,利用索引,减少子查询,以及使用连接(JOIN)替代子查询。 2. **索引策略**:Oracle提供了多种类型的索引,如B树索引、位图索引、函数索引等。选择正确的索引...
8. **存储过程和函数优化**:优化存储过程和函数,包括减少调用次数,使用绑定变量,以及避免在过程中进行大事务。 9. **性能监控和诊断**:书中可能还会讲解如何使用Oracle的性能监视工具(如AWR报告、ASH分析),...
在解析阶段,ORACLE 会检查语法、语义和权限,并合并视图定义和子查询。然后,在绑定阶段,ORACLE 会查找绑定变量并赋值。在执行阶段,ORACLE 会应用执行计划并执行必要的 I/O 和排序操作。最后,在提取阶段,ORACLE...
此外,避免使用in/exists、not in/not exists子查询,转而采用直接连接的方式也是提高性能的有效手段。这些子查询可能导致全表扫描和多次表访问,尤其是在数据量大的情况下,性能开销显著。例如,使用NOT IN或NOT ...
5. **使用绑定变量**:避免硬解析,使用绑定变量可以重用执行计划,减少解析开销,尤其在处理大量相似查询时。 6. **减少行处理**:通过限制返回的行数,如使用`FETCH FIRST n ROWS ONLY`或`LIMIT`,可以降低I/O和...
在Oracle数据库中,分页查询是一项...总的来说,实现Oracle数据库中的分页查询需要理解ROWNUM的特性和正确使用子查询或存储过程。通过合理利用这些技术,开发人员可以在保证性能的同时,为用户提供流畅的分页浏览体验。
1. INNER JOIN通常比子查询和NOT IN更高效,特别是在处理大数据量时。 2. 优先考虑使用ANSI SQL-92标准的JOIN语法,避免嵌套查询和子查询。 案例:`SELECT t1.* FROM table1 t1 WHERE t1.id IN (SELECT t2.id FROM...
4. **子查询优化**:尽可能将子查询转化为连接查询,或者使用关联子查询,减少数据处理的复杂度。 二、查询语句优化 1. **避免全表扫描**:通过WHERE子句准确筛选数据,避免无谓的数据扫描。 2. **限制返回行数**...
例如,可以使用索引、分区表、子查询等技术来优化 SQL 语句。此外,使用游标变量也可以提高查询效率。 cursor variables 游标变量是 Oracle 10g 数据库中的一种特殊变量,可以用来存储查询结果。通过使用游标...
可以考虑使用连接操作替换子查询,或者利用exists和in子句优化查询结构。 6. **物化视图**:对于固定查询模式,可以创建物化视图来预先计算结果,提供快速的数据访问。但需注意更新维护的成本。 7. **表分区**:大...
6. **优化子查询**:减少子查询的使用,或利用关联子查询替代嵌套子查询,提高查询效率。 7. **注意排序和分组操作**:排序和分组操作会消耗大量资源,尽可能利用索引进行排序,避免不必要的全表排序。 8. **监控...