sql 语句中or条件之种种情况--
2009-08-17 09:16
639 查看
sql 语句中or条件之种种情况
1、相同字段or条件,转换为inlist 走index range scan
SQL> select * from test_or a
2 where a.object_id=20 or a.object_id=21;
执行计划
----------------------------------------------------------
Plan hash value: 114014695
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 172 | 4 (0)| 00:00:01 |
| 1 | INLIST ITERATOR | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 2 | 172 | 4 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | I_TEST_OR_1 | 2 | | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("A"."OBJECT_ID"=20 OR "A"."OBJECT_ID"=21)
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
7 consistent gets
2、不同字段or条件,可分别index scan
SQL> select * from test_or a
2 where a.object_id=20 or a.object_name='ICOL$';
执行计划
----------------------------------------------------------
Plan hash value: 3681382264
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 258 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID | TEST_OR | 3 | 258 | 3 (0)| 00:00:01 |
| 2 | BITMAP CONVERSION TO ROWIDS | | | | | |
| 3 | BITMAP OR | | | | | |
| 4 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 5 | INDEX RANGE SCAN | I_TEST_OR_2 | | | 1 (0)| 00:00:01 |
| 6 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 7 | INDEX RANGE SCAN | I_TEST_OR_1 | | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("A"."OBJECT_NAME"='ICOL$')
7 - access("A"."OBJECT_ID"=20)
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
5 consistent gets
由于这里的行数很少,oracle 选择了bitmap conversion,事实上相比concatenation也是比较高效的
SQL> select /*+use_concat*/* from test_or a
2 where a.object_id=20 or a.object_name='ICOL$';
执行计划
----------------------------------------------------------
Plan hash value: 1192526883
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 258 | 5 (0)| 00:00:01 |
| 1 | CONCATENATION | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 1 | 86 | 2 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | | 1 (0)| 00:00:01 |
|* 4 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 2 | 172 | 3 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | I_TEST_OR_2 | 2 | | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("A"."OBJECT_ID"=20)
4 - filter(LNNVL("A"."OBJECT_ID"=20))
5 - access("A"."OBJECT_NAME"='ICOL$')
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
7 consistent gets
3、不同表上or条件,可以看到任然能够正确选择index range scan
SQL> select * from test_or a ,test_or b
2 where a.object_id=b.object_id
3 and (a.object_name='ICOL$'
4 or b.object_name='ICOL$');
执行计划
----------------------------------------------------------
Plan hash value: 2828610916
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 688 | 14 (0)| 00:00:01 |
| 1 | CONCATENATION | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID | TEST_OR | 1 | 86 | 2 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | 2 | 344 | 7 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 2 | 172 | 3 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | I_TEST_OR_2 | 2 | | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | | 1 (0)| 00:00:01 |
|* 7 | TABLE ACCESS BY INDEX ROWID | TEST_OR | 1 | 86 | 2 (0)| 00:00:01 |
| 8 | NESTED LOOPS | | 2 | 344 | 7 (0)| 00:00:01 |
| 9 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 2 | 172 | 3 (0)| 00:00:01 |
|* 10 | INDEX RANGE SCAN | I_TEST_OR_2 | 2 | | 1 (0)| 00:00:01 |
|* 11 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("B"."OBJECT_NAME"='ICOL$')
6 - access("A"."OBJECT_ID"="B"."OBJECT_ID")
7 - filter(LNNVL("B"."OBJECT_NAME"='ICOL$'))
10 - access("A"."OBJECT_NAME"='ICOL$')
11 - access("A"."OBJECT_ID"="B"."OBJECT_ID")
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
14 consistent gets
4、or条件中有一个为子查询的情况,无法index scan
SQL> select * from test_or a
2 where a.object_id in (select object_id from test_or b where b.object_id=20)
3 or a.object_id=20;
执行计划
----------------------------------------------------------
Plan hash value: 4077212359
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1602 | 134K| 96 (3)| 00:00:02 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL| TEST_OR | 32012 | 2688K| 96 (3)| 00:00:02 |
|* 3 | FILTER | | | | | |
|* 4 | INDEX RANGE SCAN| I_TEST_OR_1 | 1 | 5 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("A"."OBJECT_ID"=20 OR EXISTS (SELECT /*+ */ 0 FROM
"TEST_OR" "B" WHERE :B1=20 AND "OBJECT_ID"=:B2))
3 - filter(:B1=20)
4 - access("OBJECT_ID"=:B1)
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
411 consistent gets
使用use_concat也无效
SQL> select /*+use_concat*/* from test_or a
2 where a.object_id in (select object_id from test_or b where b.object_id=20)
3 or a.object_id=20;
执行计划
----------------------------------------------------------
Plan hash value: 4077212359
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1602 | 134K| 96 (3)| 00:00:02 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL| TEST_OR | 32012 | 2688K| 96 (3)| 00:00:02 |
|* 3 | FILTER | | | | | |
|* 4 | INDEX RANGE SCAN| I_TEST_OR_1 | 1 | 5 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------
5、修改成union可应用index
SQL> select * from test_or a
2 where a.object_id in (select object_id from test_or b where b.object_id=20)
3 union
4 select * from test_or a
5 where a.object_id=20;
执行计划
----------------------------------------------------------
Plan hash value: 614230733
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 177 | 7 (58)| 00:00:01 |
| 1 | SORT UNIQUE | | 2 | 177 | 7 (58)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
| 3 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 1 | 86 | 2 (0)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 | 91 | 3 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | 5 | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | | 1 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 1 | 86 | 2 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("B"."OBJECT_ID"=20)
6 - access("A"."OBJECT_ID"=20)
8 - access("A"."OBJECT_ID"=20)
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
8 consistent gets
6、利用precompute_subquery也可利用上索引
SQL> select * from test_or a
2 where a.object_id in (select /*+ precompute_subquery */ object_id from test_or b where b.object_id=20)
3 or a.object_name='ICOL$';
执行计划
----------------------------------------------------------
Plan hash value: 3681382264
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 258 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID | TEST_OR | 3 | 258 | 3 (0)| 00:00:01 |
| 2 | BITMAP CONVERSION TO ROWIDS | | | | | |
| 3 | BITMAP OR | | | | | |
| 4 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 5 | INDEX RANGE SCAN | I_TEST_OR_2 | | | 1 (0)| 00:00:01 |
| 6 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 7 | INDEX RANGE SCAN | I_TEST_OR_1 | | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("A"."OBJECT_NAME"='ICOL$')
7 - access("A"."OBJECT_ID"=20)
统计信息
----------------------------------------------------------
5 recursive calls
0 db block gets
7 consistent gets
7、
SQL> select * from test_or a
2 where a.object_id in (select /*+precompute_subquery */ object_id from test_or b where b.object_id=20)
3 or a.object_id=20;
执行计划
----------------------------------------------------------
Plan hash value: 2170966137
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 86 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 1 | 86 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"."OBJECT_ID"=20)
统计信息
----------------------------------------------------------
5 recursive calls
0 db block gets
6 consistent gets
SQL> select * from test_or a
2 where a.object_id in (select /*+precompute_subquery */ object_id from test_or b where b.object_id=20)
3 or a.object_id=21;
执行计划
----------------------------------------------------------
Plan hash value: 114014695
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 172 | 4 (0)| 00:00:01 |
| 1 | INLIST ITERATOR | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 2 | 172 | 4 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | I_TEST_OR_1 | 2 | | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("A"."OBJECT_ID"=20 OR "A"."OBJECT_ID"=21)
统计信息
----------------------------------------------------------
4 recursive calls
0 db block gets
9 consistent gets
可以看到 /*+precompute_subquery */后子查询被转换成了or条件,从而可以使用index
但这将导致的一个问题是recursive calls会随着子查询的结果集增加,如果子查询结果集很大,可能会带来额外的开销
如:
SQL> select * from test_or a
2 where a.object_id in (select /*+precompute_subquery */ object_id from test_or b where b.object_id<2
3 or a.object_id=21;
已选择19行。
执行计划
----------------------------------------------------------
Plan hash value: 114014695
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 19 | 1634 | 17 (0)| 00:00:01 |
| 1 | INLIST ITERATOR | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 19 | 1634 | 17 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | I_TEST_OR_1 | 19 | | 16 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("A"."OBJECT_ID"=2 OR "A"."OBJECT_ID"=3 OR "A"."OBJECT_ID"=4 OR
"A"."OBJECT_ID"=5 OR "A"."OBJECT_ID"=6 OR "A"."OBJECT_ID"=7 OR "A"."OBJECT_ID"=8 OR
"A"."OBJECT_ID"=9 OR "A"."OBJECT_ID"=10 OR "A"."OBJECT_ID"=11 OR "A"."OBJECT_ID"=12
OR "A"."OBJECT_ID"=13 OR "A"."OBJECT_ID"=14 OR "A"."OBJECT_ID"=15 OR
"A"."OBJECT_ID"=16 OR "A"."OBJECT_ID"=17 OR "A"."OBJECT_ID"=18 OR
"A"."OBJECT_ID"=19 OR "A"."OBJECT_ID"=21)
统计信息
----------------------------------------------------------
22 recursive calls
0 db block gets
78 consistent gets
----------------------------------------------------------------------------------------------------------------------
create table test_or as select * from dba_objects
create index i_test_or_1 on test_or (object_id)
create index i_test_or_2 on test_or (object_name)
-----------------------------------------------------------------------------------------------------------------------
性能优化群79801530
1、相同字段or条件,转换为inlist 走index range scan
SQL> select * from test_or a
2 where a.object_id=20 or a.object_id=21;
执行计划
----------------------------------------------------------
Plan hash value: 114014695
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 172 | 4 (0)| 00:00:01 |
| 1 | INLIST ITERATOR | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 2 | 172 | 4 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | I_TEST_OR_1 | 2 | | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("A"."OBJECT_ID"=20 OR "A"."OBJECT_ID"=21)
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
7 consistent gets
2、不同字段or条件,可分别index scan
SQL> select * from test_or a
2 where a.object_id=20 or a.object_name='ICOL$';
执行计划
----------------------------------------------------------
Plan hash value: 3681382264
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 258 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID | TEST_OR | 3 | 258 | 3 (0)| 00:00:01 |
| 2 | BITMAP CONVERSION TO ROWIDS | | | | | |
| 3 | BITMAP OR | | | | | |
| 4 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 5 | INDEX RANGE SCAN | I_TEST_OR_2 | | | 1 (0)| 00:00:01 |
| 6 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 7 | INDEX RANGE SCAN | I_TEST_OR_1 | | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("A"."OBJECT_NAME"='ICOL$')
7 - access("A"."OBJECT_ID"=20)
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
5 consistent gets
由于这里的行数很少,oracle 选择了bitmap conversion,事实上相比concatenation也是比较高效的
SQL> select /*+use_concat*/* from test_or a
2 where a.object_id=20 or a.object_name='ICOL$';
执行计划
----------------------------------------------------------
Plan hash value: 1192526883
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 258 | 5 (0)| 00:00:01 |
| 1 | CONCATENATION | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 1 | 86 | 2 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | | 1 (0)| 00:00:01 |
|* 4 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 2 | 172 | 3 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | I_TEST_OR_2 | 2 | | 1 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("A"."OBJECT_ID"=20)
4 - filter(LNNVL("A"."OBJECT_ID"=20))
5 - access("A"."OBJECT_NAME"='ICOL$')
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
7 consistent gets
3、不同表上or条件,可以看到任然能够正确选择index range scan
SQL> select * from test_or a ,test_or b
2 where a.object_id=b.object_id
3 and (a.object_name='ICOL$'
4 or b.object_name='ICOL$');
执行计划
----------------------------------------------------------
Plan hash value: 2828610916
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 688 | 14 (0)| 00:00:01 |
| 1 | CONCATENATION | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID | TEST_OR | 1 | 86 | 2 (0)| 00:00:01 |
| 3 | NESTED LOOPS | | 2 | 344 | 7 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 2 | 172 | 3 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | I_TEST_OR_2 | 2 | | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | | 1 (0)| 00:00:01 |
|* 7 | TABLE ACCESS BY INDEX ROWID | TEST_OR | 1 | 86 | 2 (0)| 00:00:01 |
| 8 | NESTED LOOPS | | 2 | 344 | 7 (0)| 00:00:01 |
| 9 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 2 | 172 | 3 (0)| 00:00:01 |
|* 10 | INDEX RANGE SCAN | I_TEST_OR_2 | 2 | | 1 (0)| 00:00:01 |
|* 11 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("B"."OBJECT_NAME"='ICOL$')
6 - access("A"."OBJECT_ID"="B"."OBJECT_ID")
7 - filter(LNNVL("B"."OBJECT_NAME"='ICOL$'))
10 - access("A"."OBJECT_NAME"='ICOL$')
11 - access("A"."OBJECT_ID"="B"."OBJECT_ID")
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
14 consistent gets
4、or条件中有一个为子查询的情况,无法index scan
SQL> select * from test_or a
2 where a.object_id in (select object_id from test_or b where b.object_id=20)
3 or a.object_id=20;
执行计划
----------------------------------------------------------
Plan hash value: 4077212359
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1602 | 134K| 96 (3)| 00:00:02 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL| TEST_OR | 32012 | 2688K| 96 (3)| 00:00:02 |
|* 3 | FILTER | | | | | |
|* 4 | INDEX RANGE SCAN| I_TEST_OR_1 | 1 | 5 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("A"."OBJECT_ID"=20 OR EXISTS (SELECT /*+ */ 0 FROM
"TEST_OR" "B" WHERE :B1=20 AND "OBJECT_ID"=:B2))
3 - filter(:B1=20)
4 - access("OBJECT_ID"=:B1)
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
411 consistent gets
使用use_concat也无效
SQL> select /*+use_concat*/* from test_or a
2 where a.object_id in (select object_id from test_or b where b.object_id=20)
3 or a.object_id=20;
执行计划
----------------------------------------------------------
Plan hash value: 4077212359
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1602 | 134K| 96 (3)| 00:00:02 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL| TEST_OR | 32012 | 2688K| 96 (3)| 00:00:02 |
|* 3 | FILTER | | | | | |
|* 4 | INDEX RANGE SCAN| I_TEST_OR_1 | 1 | 5 | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------
5、修改成union可应用index
SQL> select * from test_or a
2 where a.object_id in (select object_id from test_or b where b.object_id=20)
3 union
4 select * from test_or a
5 where a.object_id=20;
执行计划
----------------------------------------------------------
Plan hash value: 614230733
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 177 | 7 (58)| 00:00:01 |
| 1 | SORT UNIQUE | | 2 | 177 | 7 (58)| 00:00:01 |
| 2 | UNION-ALL | | | | | |
| 3 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 1 | 86 | 2 (0)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 | 91 | 3 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | 5 | 1 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | | 1 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 1 | 86 | 2 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("B"."OBJECT_ID"=20)
6 - access("A"."OBJECT_ID"=20)
8 - access("A"."OBJECT_ID"=20)
统计信息
----------------------------------------------------------
1 recursive calls
0 db block gets
8 consistent gets
6、利用precompute_subquery也可利用上索引
SQL> select * from test_or a
2 where a.object_id in (select /*+ precompute_subquery */ object_id from test_or b where b.object_id=20)
3 or a.object_name='ICOL$';
执行计划
----------------------------------------------------------
Plan hash value: 3681382264
------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 3 | 258 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID | TEST_OR | 3 | 258 | 3 (0)| 00:00:01 |
| 2 | BITMAP CONVERSION TO ROWIDS | | | | | |
| 3 | BITMAP OR | | | | | |
| 4 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 5 | INDEX RANGE SCAN | I_TEST_OR_2 | | | 1 (0)| 00:00:01 |
| 6 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 7 | INDEX RANGE SCAN | I_TEST_OR_1 | | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
5 - access("A"."OBJECT_NAME"='ICOL$')
7 - access("A"."OBJECT_ID"=20)
统计信息
----------------------------------------------------------
5 recursive calls
0 db block gets
7 consistent gets
7、
SQL> select * from test_or a
2 where a.object_id in (select /*+precompute_subquery */ object_id from test_or b where b.object_id=20)
3 or a.object_id=20;
执行计划
----------------------------------------------------------
Plan hash value: 2170966137
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 86 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 1 | 86 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | I_TEST_OR_1 | 1 | | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"."OBJECT_ID"=20)
统计信息
----------------------------------------------------------
5 recursive calls
0 db block gets
6 consistent gets
SQL> select * from test_or a
2 where a.object_id in (select /*+precompute_subquery */ object_id from test_or b where b.object_id=20)
3 or a.object_id=21;
执行计划
----------------------------------------------------------
Plan hash value: 114014695
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 172 | 4 (0)| 00:00:01 |
| 1 | INLIST ITERATOR | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 2 | 172 | 4 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | I_TEST_OR_1 | 2 | | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("A"."OBJECT_ID"=20 OR "A"."OBJECT_ID"=21)
统计信息
----------------------------------------------------------
4 recursive calls
0 db block gets
9 consistent gets
可以看到 /*+precompute_subquery */后子查询被转换成了or条件,从而可以使用index
但这将导致的一个问题是recursive calls会随着子查询的结果集增加,如果子查询结果集很大,可能会带来额外的开销
如:
SQL> select * from test_or a
2 where a.object_id in (select /*+precompute_subquery */ object_id from test_or b where b.object_id<2
3 or a.object_id=21;
已选择19行。
执行计划
----------------------------------------------------------
Plan hash value: 114014695
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 19 | 1634 | 17 (0)| 00:00:01 |
| 1 | INLIST ITERATOR | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST_OR | 19 | 1634 | 17 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | I_TEST_OR_1 | 19 | | 16 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("A"."OBJECT_ID"=2 OR "A"."OBJECT_ID"=3 OR "A"."OBJECT_ID"=4 OR
"A"."OBJECT_ID"=5 OR "A"."OBJECT_ID"=6 OR "A"."OBJECT_ID"=7 OR "A"."OBJECT_ID"=8 OR
"A"."OBJECT_ID"=9 OR "A"."OBJECT_ID"=10 OR "A"."OBJECT_ID"=11 OR "A"."OBJECT_ID"=12
OR "A"."OBJECT_ID"=13 OR "A"."OBJECT_ID"=14 OR "A"."OBJECT_ID"=15 OR
"A"."OBJECT_ID"=16 OR "A"."OBJECT_ID"=17 OR "A"."OBJECT_ID"=18 OR
"A"."OBJECT_ID"=19 OR "A"."OBJECT_ID"=21)
统计信息
----------------------------------------------------------
22 recursive calls
0 db block gets
78 consistent gets
----------------------------------------------------------------------------------------------------------------------
create table test_or as select * from dba_objects
create index i_test_or_1 on test_or (object_id)
create index i_test_or_2 on test_or (object_name)
-----------------------------------------------------------------------------------------------------------------------
性能优化群79801530
相关文章推荐
- sql 语句中or条件之种种情况
- SqlServer Update更新语句因where条件不正确 造成更新全表的情况
- SQL语句中OR条件的用法(常量取等或者不等)
- sql语句中or条件有无括号举例!!
- 替代SQL语句WHERE条件中OR关键词
- 判断几个参数的不同状态,不同的情况写SQL语句判断条件,优化做法(仅供新手)
- 在SQL SERVER 2000中写字符型的SQL语句遇到的情况
- OpenJPA查询生成的SQL语句,为何Or后面没有括号
- oracle sql 语句中where条件中 1=1 是什么意思
- oracle关于查询空间使用情况的几个sql语句
- 尽量避免在SQL语句中使用OR
- sql 2005 新增的查看sql语句运行情况
- SQL语句Where中使用别名作为判断条件
- 87 thinkphp 和sql查询条件为某字段不为空的情况
- T-SQL语句之case when then 多条件判断
- 【优达学城测评】SQL 询问语句,并列两个条件的3种写法(4)
- Oracle 查看表空间的大小及使用情况sql语句
- SQL语句增加虚拟字段,并根据情况显示不同的数据。。。(已阅。。。未阅。。)
- 使用反射让linq实现动态查询, 类似拼接sql语句的where 条件
- 应用Druid监控SQL语句的执行情况