oracle in與exists 的區別
表的分佈情況 採用cbo 資料和索引都已分析
tb_role 為8960行 建有parent_id的索引
tb_user 為8541行 建有role_id的索引
SQL> select id, role_id, login
2 from tb_user e
3 where Exists (Select ID
4 From tb_role f
5 where e.role_id = f.id
6 Connect By Prior Id = parent_id
7 Start With Id = 1);
8369 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=1292 Card=428 Bytes=
9416)
1 0 FILTER
2 1 TABLE ACCESS (FULL) OF 'tb_user' (Cost=8 Card=428 Byte
s=9416)
3 1 FILTER
4 3 CONNECT BY (WITH FILTERING)
5 4 NESTED LOOPS
6 5 INDEX (UNIQUE SCAN) OF 'PK_tb_role' (UNIQUE)
(Cost=1 Card=1 Bytes=5)
7 5 TABLE ACCESS (BY USER ROWID) OF 'tb_role'
8 4 NESTED LOOPS
9 8 BUFFER (SORT)
10 9 CONNECT BY PUMP
11 8 TABLE ACCESS (BY INDEX ROWID) OF 'tb_role' (
Cost=3 Card=18 Bytes=162)
12 11 INDEX (RANGE SCAN) OF 'INX_tb_role_PARENT_
ID' (NON-UNIQUE) (Cost=1 Card=18)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
84313553 consistent gets
0 physical reads
0 redo size
224163 bytes sent via SQL*Net to client
6553 bytes received via SQL*Net from client
559 SQL*Net roundtrips to/from client
142392 sorts (memory)
0 sorts (disk)
8369 rows processed
SQL>
一致性讀達到 84313553 consistent gets ,而造成資料很慢查出來
改用in的方式 一致性讀馬上降低到10250 ,馬上查出資料
SQL> select id, role_id, login
2 from tb_user e
3 where role_id in (Select ID
4 From tb_role f
5 Connect By Prior Id = parent_id
6 Start With Id = 1);
8369 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=14 Card=18 Bytes=630
)
1 0 HASH JOIN (SEMI) (Cost=14 Card=18 Bytes=630)
2 1 TABLE ACCESS (FULL) OF 'tb_user' (Cost=8 Card=8556 Byt
es=188232)
3 1 VIEW OF 'VW_NSO_1' (Cost=3 Card=18 Bytes=234)
4 3 CONNECT BY (WITH FILTERING)
5 4 NESTED LOOPS
6 5 INDEX (UNIQUE SCAN) OF 'PK_tb_role' (UNIQUE)
(Cost=1 Card=1 Bytes=5)
7 5 TABLE ACCESS (BY USER ROWID) OF 'tb_role'
8 4 NESTED LOOPS
9 8 BUFFER (SORT)
10 9 CONNECT BY PUMP
11 8 TABLE ACCESS (BY INDEX ROWID) OF 'tb_role' (
Cost=3 Card=18 Bytes=162)
12 11 INDEX (RANGE SCAN) OF 'INX_tb_role_PARENT_
ID' (NON-UNIQUE) (Cost=1 Card=18)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
10250 consistent gets
0 physical reads
0 redo size
224163 bytes sent via SQL*Net to client
6553 bytes received via SQL*Net from client
559 SQL*Net roundtrips to/from client
17 sorts (memory)
0 sorts (disk)
8369 rows processed
tb_user 為8541行 建有role_id的索引
SQL> select id, role_id, login
2 from tb_user e
3 where Exists (Select ID
4 From tb_role f
5 where e.role_id = f.id
6 Connect By Prior Id = parent_id
7 Start With Id = 1);
8369 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=1292 Card=428 Bytes=
9416)
1 0 FILTER
2 1 TABLE ACCESS (FULL) OF 'tb_user' (Cost=8 Card=428 Byte
s=9416)
3 1 FILTER
4 3 CONNECT BY (WITH FILTERING)
5 4 NESTED LOOPS
6 5 INDEX (UNIQUE SCAN) OF 'PK_tb_role' (UNIQUE)
(Cost=1 Card=1 Bytes=5)
7 5 TABLE ACCESS (BY USER ROWID) OF 'tb_role'
8 4 NESTED LOOPS
9 8 BUFFER (SORT)
10 9 CONNECT BY PUMP
11 8 TABLE ACCESS (BY INDEX ROWID) OF 'tb_role' (
Cost=3 Card=18 Bytes=162)
12 11 INDEX (RANGE SCAN) OF 'INX_tb_role_PARENT_
ID' (NON-UNIQUE) (Cost=1 Card=18)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
84313553 consistent gets
0 physical reads
0 redo size
224163 bytes sent via SQL*Net to client
6553 bytes received via SQL*Net from client
559 SQL*Net roundtrips to/from client
142392 sorts (memory)
0 sorts (disk)
8369 rows processed
SQL>
一致性讀達到 84313553 consistent gets ,而造成資料很慢查出來
改用in的方式 一致性讀馬上降低到10250 ,馬上查出資料
SQL> select id, role_id, login
2 from tb_user e
3 where role_id in (Select ID
4 From tb_role f
5 Connect By Prior Id = parent_id
6 Start With Id = 1);
8369 rows selected.
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT ptimizer=CHOOSE (Cost=14 Card=18 Bytes=630
)
1 0 HASH JOIN (SEMI) (Cost=14 Card=18 Bytes=630)
2 1 TABLE ACCESS (FULL) OF 'tb_user' (Cost=8 Card=8556 Byt
es=188232)
3 1 VIEW OF 'VW_NSO_1' (Cost=3 Card=18 Bytes=234)
4 3 CONNECT BY (WITH FILTERING)
5 4 NESTED LOOPS
6 5 INDEX (UNIQUE SCAN) OF 'PK_tb_role' (UNIQUE)
(Cost=1 Card=1 Bytes=5)
7 5 TABLE ACCESS (BY USER ROWID) OF 'tb_role'
8 4 NESTED LOOPS
9 8 BUFFER (SORT)
10 9 CONNECT BY PUMP
11 8 TABLE ACCESS (BY INDEX ROWID) OF 'tb_role' (
Cost=3 Card=18 Bytes=162)
12 11 INDEX (RANGE SCAN) OF 'INX_tb_role_PARENT_
ID' (NON-UNIQUE) (Cost=1 Card=18)
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
10250 consistent gets
0 physical reads
0 redo size
224163 bytes sent via SQL*Net to client
6553 bytes received via SQL*Net from client
559 SQL*Net roundtrips to/from client
17 sorts (memory)
0 sorts (disk)
8369 rows processed
目前修改sql有這幾種方式:
1.改成表的連線寫法
select id, role_id, login
from tb_user e,(Select ID
From tb_role f
Connect By Prior Id = parent_id
Start With Id = 1)d
where d.id = e.role_id;
from tb_user e,(Select ID
From tb_role f
Connect By Prior Id = parent_id
Start With Id = 1)d
where d.id = e.role_id;
2.改成用in的方式 如上所示
3.改成exists 的寫法
SQL> select id, role_id, login
2 from tb_user e
3 where Exists (select id
4 from (Select ID
5 From tb_role f
6 Connect By Prior Id = parent_id
7 Start With Id = 1)
8 where id = e.role_id);
2 from tb_user e
3 where Exists (select id
4 from (Select ID
5 From tb_role f
6 Connect By Prior Id = parent_id
7 Start With Id = 1)
8 where id = e.role_id);
具體討論,可以參考以下連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7199859/viewspace-235712/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- NOT IN 與NOT EXISTS的區別何在?
- exists和not exists及in和not in的用法與區別
- oracle中in和exists的區別Oracle
- EXISTS、IN、NOT EXISTS、NOT IN的區別(ZT)
- oracle sql tuning_in與exists的區別_轉摘OracleSQL
- (轉)ORACLE 中IN和EXISTS的區別Oracle
- 詳解not in與not exists的區別與用法
- 大神級回答exists與in的區別
- EXISTS、IN、NOT EXISTS、NOT IN用法區別
- [精選] SQL中的IN與NOT IN、EXISTS與NOT EXISTS的區別及效能分析SQL
- 對線面試官:SQL中的IN與NOT IN、EXISTS與NOT EXISTS的區別及效能分析面試SQL
- in 和 exists區別
- 子查詢中的IN與EXISTS的區別(轉)
- 在關聯子查詢中in與exists的區別
- SQL語句中exists和in的區別SQL
- in和exists的一些區別
- SQL中IN和EXISTS用法的區別SQL
- fs.exists 與 fs.access的區別是什麼
- mysql與Oracle的區別MySqlOracle
- Oracle - @和@@、&與&& 的區別Oracle
- NOT IN ,NOT EXISTS 區別 11G改變
- oracle restore與recover的區別OracleREST
- oracle truncate 與 delete 的區別Oracledelete
- [Oracle] exists 和 not existsOracle
- oracle sql_not exists與null的測試OracleSQLNull
- Oracle與OpenJDK之間的區別OracleJDK
- oracle ADG與DG的區別Oracle
- Mysql與Oracle的50個區別MySqlOracle
- SQL中IN,NOT IN,EXISTS,NOT EXISTS的用法和差別SQL
- 【oracle rowid與rownum的使用與區別 】Oracle
- oracle中的exists 和not exists 用法詳解Oracle
- Oracle與MySQL的幾點區別(轉)OracleMySql
- Oracle FailSafe與rac的聯絡與區別OracleAI
- oracle中的exists和not exists和in用法詳解Oracle
- oracle中的exists理解Oracle
- Oracle FailSafe與rac的聯絡與區別(zt)OracleAI
- oracle exists and not existOracle
- oracle中char與varchar2的區別Oracle