一次sql執行效率的討論
http://www.itpub.net/406784.html
在測試機上測試了一把
發現和樓主測試的結構有些不同
表,索引,索引欄位已經分析過.
我感覺區別在
1 NL探測Inner table的次數和這個結果記錄數.
2 子查詢效率,INDEX FAST FULL SCAN 代價.
[PHP]
SQL>
SQL> select count(*) from track;
COUNT(*)
----------
12337495
Elapsed: 00:00:00.01
SQL> select count(*) from terminal_user;
COUNT(*)
----------
305
Elapsed: 00:00:00.00
SQL>
SQL> set autotrace traceonly
SQL>
SQL>
SQL> select tu.* from terminal_user tu
2 where tu.tu_id not in (select distinct tu_id from track);
36 rows selected.
Elapsed: 00:00:00.02
Execution Plan
----------------------------------------------------------
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 27 | 1944 | 614 (1)|
| 1 | NESTED LOOPS ANTI | | 27 | 1944 | 614 (1)|
| 2 | TABLE ACCESS FULL| TERMINAL_USER | 305 | 20740 | 3 (0)|
|* 3 | INDEX RANGE SCAN | TRACK_TUID_IDX | 11M| 42M| 2 (0)|
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("TU"."TU_ID"="TU_ID")
Note
-----
- 'PLAN_TABLE' is old version
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
627 consistent gets
0 physical reads
80 redo size
4224 bytes sent via SQL*Net to client
491 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
36 rows processed
由於terminal_user 僅有305條記錄,
而且track表相關欄位有索引,INDEX RANGE SCAN使得探測發揮了很高的效率.因此這個NL效率很高.
我們看到整個sql執行的Cost僅為614。
再來看 outer jion + null condition
SQL>
SQL> select tu.*
2 from terminal_user tu,
( select distinct tu_id from track ) tk
where tu.tu_id = tk.tu_id(+)
and tk.tu_id is null; 3 4 5
36 rows selected.
Elapsed: 00:00:03.15
Execution Plan
----------------------------------------------------------
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 27 | 2187 | 10897 (16)|
|* 1 | HASH JOIN RIGHT ANTI | | 27 | 2187 | 10897 (16)|
| 2 | VIEW | | 278 | 3614 | 10894 (16)|
| 3 | HASH UNIQUE | | 278 | 1112 | 10894 (16)|
| 4 | INDEX FAST FULL SCAN| TRACK_TUID_IDX | 12M| 47M| 9365 (3)|
| 5 | TABLE ACCESS FULL | TERMINAL_USER | 305 | 20740 | 3 (0)|
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("TU"."TU_ID"="TK"."TU_ID")
Note
-----
- 'PLAN_TABLE' is old version
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
42111 consistent gets
0 physical reads
0 redo size
4224 bytes sent via SQL*Net to client
491 bytes received via SQL*Net from client
4 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
36 rows processed
我們可以看到 select distinct tu_id from track 的訪問路徑為 INDEX FAST FULL SCAN
而Cost就為9365.
SQL> select distinct tu_id from track;
278 rows selected.
Elapsed: 00:00:03.27
Execution Plan
----------------------------------------------------------
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 278 | 1112 | 10894 (16)|
| 1 | HASH UNIQUE | | 278 | 1112 | 10894 (16)|
| 2 | INDEX FAST FULL SCAN| TRACK_BK_TUID_IDX | 12M| 47M| 9365 (3)|
--------------------------------------------------------------------------------
Note
-----
- 'PLAN_TABLE' is old version
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
42180 consistent gets
0 physical reads
124 redo size
5627 bytes sent via SQL*Net to client
667 bytes received via SQL*Net from client
20 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
278 rows processed
SQL> select /*+ INDEX(track,TRACK_BK_TUID_IDX)*/ distinct tu_id from track
2 ;
278 rows selected.
Elapsed: 00:00:03.69
Execution Plan
----------------------------------------------------------
-----------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)|
-----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 278 | 1112 | 43705 (5)|
| 1 | SORT UNIQUE NOSORT| | 278 | 1112 | 43705 (5)|
| 2 | INDEX FULL SCAN | TRACK_BK_TUID_IDX | 12M| 47M| 42176 (1)|
-----------------------------------------------------------------------------
Note
-----
- 'PLAN_TABLE' is old version
Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
41907 consistent gets
0 physical reads
132 redo size
5627 bytes sent via SQL*Net to client
667 bytes received via SQL*Net from client
20 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
278 rows processed
我發現select distinct tu_id from track無論是FFS還是IFS效率都不怎麼樣.
所以這裡就產生一個問題.子查詢的效率會受到資料量(影響到索引段的大小)的影響.
SQL> set autotrace off
SQL> analyze index TRACK_BK_TUID_IDX validate structure;
Index analyzed.
Elapsed: 00:00:15.65
SQL> select BLOCKS,USED_SPACE,DISTINCT_KEYS,LF_ROWS_LEN from index_stats;
BLOCKS USED_SPACE DISTINCT_KEYS LF_ROWS_LEN
---------- ---------- ------------- -----------
42752 198198860 278 197520787
[/PHP]
所以我感覺還是多做測試,用事實說話.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/76065/viewspace-838204/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 利用並行提高sql執行效率(轉)並行SQL
- 面試場景題:一次關於執行緒池使用場景的討論。面試執行緒
- 記一次,因表變數導致SQL執行效率變慢變數SQL
- Java執行緒的討論與應用(轉)Java執行緒
- Oracle提高SQL執行效率的三種方法ITOracleSQL
- Oracle及SQL Server Job執行時間討論及夏令時問題OracleSQLServer
- hibernate中Session的執行緒安全的討論Session執行緒
- 關於UI的一次討論——來自專案管理群的討論UI專案管理
- 決定一個SQL執行效率的是執行計劃, 而不是SQL的寫法SQL
- MySql定位執行效率較低的SQL語句MySql
- 【SQL】Oracle避免動態SQL,提高過程執行效率SQLOracle
- 一次因表變數導致SQL執行效率變慢的實戰記錄SNSR變數SQL
- Mysql之一次完成的sql執行過程MySql
- 在Oracle裡提高SQL執行效率的三種方法NQOracleSQL
- sql server中如何檢視執行效率不高的語句SQLServer
- switch執行效率
- AutoTRACE是分析SQL的執行計劃,執行效率的一個非常簡單方便的工具SQL
- 整理的一些SQL題,與討論SQL
- 【SQL】Oracle sql語句 minus函式執行效率與join對比SQLOracle函式
- mysql一次執行多個SQL檔案MySql
- MyBatis 一次執行多條SQL語句MyBatisSQL
- Android 不能在子執行緒中更新 UI 的討論和分析Android執行緒UI
- 淺談JavaScript的執行效率JavaScript
- Oracle中SQL語句執行效率的查詢與解決 (3)OracleSQL
- Oracle中SQL語句執行效率的查詢與解決 (2)OracleSQL
- Oracle中SQL語句執行效率的查詢與解決 (1)OracleSQL
- SQL的執行SQL
- Java執行緒的深入探討Java執行緒
- Java核心知識體系7:執行緒安全性討論Java執行緒
- SetUnhandledExceptionFilter 的討論ExceptionFilter
- Oracle中SQL語句執行效率問題的查詢與解決OracleSQL
- android:提升 ListView 的執行效率AndroidView
- 提高python執行效率的方法Python
- 陳皓:程式碼執行的效率
- Oracle - 執行過的SQL、正在執行的SQL、消耗資源最多的SQLOracleSQL
- document.createDocumentFragment()執行效率Fragment
- Javascript執行效率小結JavaScript
- in/exists和not in/not exists執行效率