SQL 语句访问路径的方式
全表扫描(Full Table Scans)
select * from t_Vio_Violation t
Plan Hash Value : 1218663174
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 7670989 | 4042611203 | 103263 | 00:00:09 |
| 1 | TABLE ACCESS FULL | T_VIO_VIOLATION | 7670989 | 4042611203 | 103263 | 00:00:09 |
-----------------------------------------------------------------------------------------
rowid 访问
单条件查询,rowid最快的
select rowid from t_Vio_Violation t where t.violation_id ='3321474226' -- AAAQ9lAAFAAAMSzAAH
select * from t_Vio_Violation t where rowid='AAAQ9lAAFAAAMSzAAH';
Plan Hash Value : 3532886438
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 527 | 1 | 00:00:01 |
| 1 | TABLE ACCESS BY USER ROWID | T_VIO_VIOLATION | 1 | 527 | 1 | 00:00:01 |
----------------------------------------------------------------------------------------
索引扫描(Index Scan 或 index lookup)
索引唯一扫描(index unique scan)
- 特点:
- 唯一性:索引唯一扫描只能用于唯一索引,确保每次查询返回的行数是唯一的。
- 高效性:由于索引键值是唯一的,Oracle 可以直接定位到目标行,无需进一步搜索,因此效率非常高。
- 这里的violation_id 唯一索引unique。
ITMS5_1@hfzcdb> explain plan for select * from t_Vio_Violation t where t.violation_id='3321474226';
Explained.
ITMS5_1@hfzcdb> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 4183191119
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 527 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T_VIO_VIOLATION | 1 | 527 | 3 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | SYS_C0013148 | 1 | | 2 (0)| 00:00:01 |
-----------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("T"."VIOLATION_ID"='3321474226')
14 rows selected.
ITMS5_1@hfzcdb>
索引范围扫描(index range scan)
- 特点:
- 非唯一性:索引范围扫描使用非唯一索引,允许索引键值有重复。
- 范围查询:适用于范围查询条件,如 >、<、BETWEEN、LIKE 等。
- 顺序访问:按索引顺序扫描数据,通常是从最小值到最大值。
#select rowid from t_Vio_Violation t where t.violation_id <'3321474226';
Plan Hash Value : 94343750
----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 23 | 3 | 00:00:01 |
| * 1 | INDEX RANGE SCAN | SYS_C0013148 | 1 | 23 | 3 | 00:00:01 |
----------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 1 - access("T"."VIOLATION_ID"<'3321474226')
#select rowid from t_Vio_Violation t where t.violation_id <'3321474226' order by violation_id desc;
Plan Hash Value : 1205653834
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 23 | 3 | 00:00:01 |
| * 1 | INDEX RANGE SCAN DESCENDING | SYS_C0013148 | 1 | 23 | 3 | 00:00:01 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 1 - access("T"."VIOLATION_ID"<'3321474226')
索引全扫描(index full scan)
-
特点:
-
仅访问索引:索引全扫描只读取索引数据块,不访问表的数据块。
-
顺序访问:按索引顺序访问数据,通常是从最小值到最大值。
-
不需要过滤条件:适用于没有过滤条件或过滤条件较弱的情况。
-
与全表扫描(Full Table Scan)不同,索引全扫描只访问索引数据块,而不需要访问整个表的数据块,因此在某些情况下可以显著提高查询性能。
-
#select max(t.violation_time) from t_Vio_Violation t
Plan Hash Value : 2284200782
----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 8 | 3 | 00:00:01 |
| 1 | SORT AGGREGATE | | 1 | 8 | | |
| 2 | INDEX FULL SCAN (MIN/MAX) | IDX_VIOLATION_TIME_01 | 1 | 8 | 3 | 00:00:01 |
----------------------------------------------------------------------------------------------
索引快速扫描(index fast full scan)
-
特点:
-
并行访问:索引快速全扫描并行访问所有可用的索引块,不按索引键值的顺序访问数据。
-
仅访问索引:只读取索引数据块,不访问表的数据块。
-
不排序:返回的数据不按索引键值排序。
-
#select t.violation_type from t_Vio_Violation t
Plan Hash Value : 2392038657
-----------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
-----------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 7670989 | 23012967 | 13074 | 00:00:02 |
| 1 | INDEX FAST FULL SCAN | IDX_VIOLATION_TIME_01 | 7670989 | 23012967 | 13074 | 00:00:02 |
-----------------------------------------------------------------------------------------------
索引跳跃扫描(index skip scan)
-
特点:
-
复合索引:索引跳跃扫描仅适用于复合索引,即具有多个列的索引。
-
跳过前导列:在查询中未使用的前导列(索引定义中的第一列或前几列)会被跳过,直接使用后续列进行索引扫描。
-
提高选择性:通过跳过选择性较低的前导列,可以提高后续列的选择性,从而提高查询性能
-
#select t.violation_type from t_Vio_Violation t where t.violation_type='1625A' and t.address_desc='%路口%'
Plan Hash Value : 2819657385
----------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
----------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 44 | 53690 | 00:00:05 |
| * 1 | TABLE ACCESS BY INDEX ROWID BATCHED | T_VIO_VIOLATION | 1 | 44 | 53690 | 00:00:05 |
| * 2 | INDEX SKIP SCAN | IDX_VIOLATION_TIME_01 | 25394 | | 34768 | 00:00:03 |
----------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 1 - filter("T"."ADDRESS_DESC"='%路口%')
* 2 - access("T"."VIOLATION_TYPE"='1625A')
* 2 - filter("T"."VIOLATION_TYPE"='1625A')
/*Access:表示对应的谓词条件会影响数据的访问路径(是按照索引还是表)
Filter:表示谓词条件只会起到过滤作用,不会影响数据的访问路径。
因此,需要着重关注filter部分是否可创建索引