sql中order by與索引排序的區別
SQL> conn yang/yang as sysdba
已連接。
SQL> create table t as select object_id id ,object_name name
2 from dba_objects ;
表已創建。
SQL> set autot traceonly
一次普通的全表掃描,沒有排序的!
SQL> select id ,name from t;
已選擇68372行。
執行計劃
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 64794 | 4998K| 91 (2)| 00:00:02 |
| 1 | TABLE ACCESS FULL| T | 64794 | 4998K| 91 (2)| 00:00:02 |
--------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
統計信息
----------------------------------------------------------
68 recursive calls
0 db block gets
4943 consistent gets
325 physical reads
0 redo size
2936793 bytes sent via SQL*Net to client
50554 bytes received via SQL*Net from client
4560 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
68372 rows processed
--根據id 排序!注意執行計劃裏面的TempSpc 是臨時空間seo顧問,大小11M
SQL> select id ,name from t order by id;
已選擇68372行。
執行計劃
----------------------------------------------------------
Plan hash value: 961378228
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 64794 | 4998K| | 1283 (1)| 00:00:16 |
| 1 | SORT ORDER BY | | 64794 | 4998K| 11M| 1283 (1)| 00:00:16 |
| 2 | TABLE ACCESS FULL| T | 64794 | 4998K| | 91 (2)| 00:00:02 |
-----------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
統計信息
----------------------------------------------------------
4 recursive calls
0 db block gets
394 consistent gets
0 physical reads
0 redo size
2663362 bytes sent via SQL*Net to client
50554 bytes received via SQL*Net from client
4560 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
68372 rows processed
--在表的 id 字段建立索引,並進行信息統計。
SQL> create index idx_id on t(id) ;
索引已創建。
SQL> exec dbms_stats.gather_table_stats(user ,'T',cascade => true);
PL/SQL 過程已成功完成。
SQL> select id ,name from t order by id;
已選擇68372行。
執行計劃
----------------------------------------------------------
Plan hash value: 961378228
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 68372 | 1936K| | 638 (1)| 00:00:08 |
| 1 | SORT ORDER BY | | 68372 | 1936K| 5384K| 638 (1)| 00:00:08 |
| 2 | TABLE ACCESS FULL| T | 68372 | 1936K| | 91 (2)| 00:00:02 |
-----------------------------------------------------------------------------------
統計信息
----------------------------------------------------------
151 recursive calls
0 db block gets
348 consistent gets
0 physical reads
0 redo size
2663362 bytes sent via SQL*Net to client
50554 bytes received via SQL*Net from client
4560 SQL*Net roundtrips to/from client
5 sorts (memory) --沒有使用索引比全表掃描多了四此排序。
0 sorts (disk)
68372 rows processed
--使用索引。執行計劃中沒有tempspac
SQL> select id ,name from t where id <1200 order by id;--加上了order by
已選擇1133行。
執行計劃
----------------------------------------------------------
Plan hash value: 827754323
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1167 | 33843 | 10 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1167 | 33843 | 10 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_ID | 1167 | | 4 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"<1200)
統計信息
----------------------------------------------------------
1 recursive calls
0 db block gets
160 consistent gets
0 physical reads
0 redo size
37872 bytes sent via SQL*Net to client
1241 bytes received via SQL*Net from client
77 SQL*Net roundtrips to/from client
0 sorts (memory) --這裏可以看出沒有排序!
0 sorts (disk)
1133 rows processed
小結:
如果數據直接從索引獲取,也是有序的,此時加order by,cbo不會執行sort 排序動作的。即,加上order by對性能也不會有什麼影響!
其實這裏還是有疑問的
1 根據id 排序 走全表掃描和建立了索引後信息統計上有差別,前者比後者少了3個sort 操作!而後者的TempSpc比全表掃描少了將近一半!
2 關於TempSpc 的理解如果是臨時表空間 ,就用到了磁盤排序了 ,而執行上面沒有顯示disk sort!
已連接。
SQL> create table t as select object_id id ,object_name name
2 from dba_objects ;
表已創建。
SQL> set autot traceonly
一次普通的全表掃描,沒有排序的!
SQL> select id ,name from t;
已選擇68372行。
執行計劃
----------------------------------------------------------
Plan hash value: 1601196873
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 64794 | 4998K| 91 (2)| 00:00:02 |
| 1 | TABLE ACCESS FULL| T | 64794 | 4998K| 91 (2)| 00:00:02 |
--------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
統計信息
----------------------------------------------------------
68 recursive calls
0 db block gets
4943 consistent gets
325 physical reads
0 redo size
2936793 bytes sent via SQL*Net to client
50554 bytes received via SQL*Net from client
4560 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
68372 rows processed
--根據id 排序!注意執行計劃裏面的TempSpc 是臨時空間seo顧問,大小11M
SQL> select id ,name from t order by id;
已選擇68372行。
執行計劃
----------------------------------------------------------
Plan hash value: 961378228
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 64794 | 4998K| | 1283 (1)| 00:00:16 |
| 1 | SORT ORDER BY | | 64794 | 4998K| 11M| 1283 (1)| 00:00:16 |
| 2 | TABLE ACCESS FULL| T | 64794 | 4998K| | 91 (2)| 00:00:02 |
-----------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement
統計信息
----------------------------------------------------------
4 recursive calls
0 db block gets
394 consistent gets
0 physical reads
0 redo size
2663362 bytes sent via SQL*Net to client
50554 bytes received via SQL*Net from client
4560 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
68372 rows processed
--在表的 id 字段建立索引,並進行信息統計。
SQL> create index idx_id on t(id) ;
索引已創建。
SQL> exec dbms_stats.gather_table_stats(user ,'T',cascade => true);
PL/SQL 過程已成功完成。
SQL> select id ,name from t order by id;
已選擇68372行。
執行計劃
----------------------------------------------------------
Plan hash value: 961378228
-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 68372 | 1936K| | 638 (1)| 00:00:08 |
| 1 | SORT ORDER BY | | 68372 | 1936K| 5384K| 638 (1)| 00:00:08 |
| 2 | TABLE ACCESS FULL| T | 68372 | 1936K| | 91 (2)| 00:00:02 |
-----------------------------------------------------------------------------------
統計信息
----------------------------------------------------------
151 recursive calls
0 db block gets
348 consistent gets
0 physical reads
0 redo size
2663362 bytes sent via SQL*Net to client
50554 bytes received via SQL*Net from client
4560 SQL*Net roundtrips to/from client
5 sorts (memory) --沒有使用索引比全表掃描多了四此排序。
0 sorts (disk)
68372 rows processed
--使用索引。執行計劃中沒有tempspac
SQL> select id ,name from t where id <1200 order by id;--加上了order by
已選擇1133行。
執行計劃
----------------------------------------------------------
Plan hash value: 827754323
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1167 | 33843 | 10 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1167 | 33843 | 10 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_ID | 1167 | | 4 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"<1200)
統計信息
----------------------------------------------------------
1 recursive calls
0 db block gets
160 consistent gets
0 physical reads
0 redo size
37872 bytes sent via SQL*Net to client
1241 bytes received via SQL*Net from client
77 SQL*Net roundtrips to/from client
0 sorts (memory) --這裏可以看出沒有排序!
0 sorts (disk)
1133 rows processed
小結:
如果數據直接從索引獲取,也是有序的,此時加order by,cbo不會執行sort 排序動作的。即,加上order by對性能也不會有什麼影響!
其實這裏還是有疑問的
1 根據id 排序 走全表掃描和建立了索引後信息統計上有差別,前者比後者少了3個sort 操作!而後者的TempSpc比全表掃描少了將近一半!
2 關於TempSpc 的理解如果是臨時表空間 ,就用到了磁盤排序了 ,而執行上面沒有顯示disk sort!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.