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)