转:oracle树形查询是否会全表扫描?答案:不会
2010-07-26 10:58
246 查看
oracle树形查询一定会全表扫描吗?
比如有这样的表,id是主键,parent_id列有索引,查询条件是:
start with id='xxx'
connect by parent_id= prior id
表有一百万行,查出的结果集只有几十行,按理说应该很快才对(nested loop),即使写程序来循环也很快,但Oracle似乎总是会全表扫描,导致很慢?
我做了个测试,会用到索引:
CREATE TABLE TEST
AS
SELECT ROWNUM id, ROWNUM-1 parent_id FROM DUAL CONNECT BY ROWNUM<=1E6;
ALTER TABLE TEST ADD CONSTRAINT test_pk PRIMARY KEY (ID);
CREATE INDEX TEST_X ON TEST(PARENT_ID);
SELECT * FROM TEST START WITH ID=1E6-50 CONNECT BY PARENT_ID = PRIOR ID;
Execution Plan
----------------------------------------------------------
Plan hash value: 3690598434
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 52 | 11 (19)| 00:00:01 |
|* 1 | CONNECT BY WITH FILTERING | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID | TEST | 1 | 26 | 3 (0)| 00:00:01 |
|* 3 | INDEX UNIQUE SCAN | TEST_PK | 1 | | 2 (0)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 | 39 | 6 (0)| 00:00:01 |
| 5 | CONNECT BY PUMP | | | | | |
| 6 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 26 | 3 (0)| 00:00:01 |
|* 7 | INDEX RANGE SCAN | TEST_X | 1 | | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("TEST"."PARENT_ID"=PRIOR "TEST"."ID")
3 - access("ID"=999950)
7 - access("PARENT_ID"="connect$_by$_pump$_002"."PRIOR ID")
Note
-----
- dynamic sampling used for this statement (level=2)
比如有这样的表,id是主键,parent_id列有索引,查询条件是:
start with id='xxx'
connect by parent_id= prior id
表有一百万行,查出的结果集只有几十行,按理说应该很快才对(nested loop),即使写程序来循环也很快,但Oracle似乎总是会全表扫描,导致很慢?
我做了个测试,会用到索引:
CREATE TABLE TEST
AS
SELECT ROWNUM id, ROWNUM-1 parent_id FROM DUAL CONNECT BY ROWNUM<=1E6;
ALTER TABLE TEST ADD CONSTRAINT test_pk PRIMARY KEY (ID);
CREATE INDEX TEST_X ON TEST(PARENT_ID);
SELECT * FROM TEST START WITH ID=1E6-50 CONNECT BY PARENT_ID = PRIOR ID;
Execution Plan
----------------------------------------------------------
Plan hash value: 3690598434
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 52 | 11 (19)| 00:00:01 |
|* 1 | CONNECT BY WITH FILTERING | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID | TEST | 1 | 26 | 3 (0)| 00:00:01 |
|* 3 | INDEX UNIQUE SCAN | TEST_PK | 1 | | 2 (0)| 00:00:01 |
| 4 | NESTED LOOPS | | 1 | 39 | 6 (0)| 00:00:01 |
| 5 | CONNECT BY PUMP | | | | | |
| 6 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 26 | 3 (0)| 00:00:01 |
|* 7 | INDEX RANGE SCAN | TEST_X | 1 | | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("TEST"."PARENT_ID"=PRIOR "TEST"."ID")
3 - access("ID"=999950)
7 - access("PARENT_ID"="connect$_by$_pump$_002"."PRIOR ID")
Note
-----
- dynamic sampling used for this statement (level=2)
相关文章推荐
- MySQL查询优化:LIMIT 1避免全表扫描【如判断用户是否存在select * from users where username='123' and passwd='123' limit 1】
- 不会使用索引,导致全表扫描情况
- oracle sql语句怎么查询所有存储过程中是否包含某个注释?
- oracle树形查询 start with connect by
- MySQL查询优化:LIMIT 1避免全表扫描提高查询效率
- oracle 10g 树形查询
- Oracle全表扫描
- Oracle查询表空间的使用情况和数据文件是否拓展及剩余可拓展大小
- oracle全表扫描的优化
- Mysql避免全表扫描sql查询优化
- 解析Oracle数据扫描 Oracle SQL查询优化 数据读取方式
- 不会使用索引,导致全表扫描情况
- Mysql避免全表扫描sql查询优化
- ORACLE sql调优之记录一次trim函数引发的大表全表扫描
- 整理oracle 树形查询
- oracle优化之count的优化-避免全表扫描
- oracle 性能优化操作十八: 决定使用全表扫描还是使用索引
- Oracle 数据库树形结构查询
- MYSQL查询优化:limit 1避免全表扫描
- 解析Oracle数据扫描 Oracle SQL查询优化 引导局部范围数据扫描的方法(1)