@dbsnake-用合適的函式索引來避免看似無法避免的全表掃描
昨天聽了@dbsnake的SQL方法論,感覺比第一次要更有感覺,希望對實際工作能有幫助。
昨天講到一處利用reverse函式建立索引,避免全表掃描的case,頗有感觸,拿出來試一下。
SQL> create table rev (id number, name varchar2(5));
Table created.
SQL> select * from rev;
ID NAME
---------- -----
1 abc
2 bc
3 c
SQL> create index rev_idx0 on rev(name);
Index created.
SQL> set autot on
SQL> select id, name from rev where name like '%bc';
ID NAME
---------- -----
1 abc
2 bc
Execution Plan
----------------------------------------------------------
Plan hash value: 3205185662
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 34 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| REV | 2 | 34 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("NAME" LIKE '%bc')
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
5 recursive calls
0 db block gets
16 consistent gets
0 physical reads
0 redo size
633 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
2 rows processed
這裡建立了name的B樹索引,但由於使用了%bc為條件,所以不會用索引,這裡用了全表掃描。
如何能讓%bc條件使用索引呢?這裡講到%bc不能用索引的原因是因為索引鍵值按照索引二進位制的順序排序,%在前就無法精確定位,因此無法使用索引。既然%在後面可以使用索引,那就想辦法將%的條件放在後面組織。
SQL> create index rev_idx on rev(reverse(name));
Index created.
SQL> select id, name from rev where reverse(name) like reverse('%bc');
ID NAME
---------- -----
2 bc
1 abc
Execution Plan
----------------------------------------------------------
Plan hash value: 2418054352
---------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 2 | 34 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| REV | 2 | 34 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | REV_IDX | 1 | | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access(REVERSE("NAME") LIKE 'cb%')
filter(REVERSE("NAME") LIKE 'cb%')
Note
-----
- dynamic sampling used for this statement
Statistics
----------------------------------------------------------
28 recursive calls
0 db block gets
14 consistent gets
0 physical reads
0 redo size
633 bytes sent via SQL*Net to client
492 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
2 rows processed
這裡用了reverse函式,相當於方向匹配字串bc,這樣就將前面的%放到了後面。從執行計劃看cost從3變為2。
注:
這裡可以看到無論哪次執行,物理讀都是0,原因我覺得就是第一次執行過一個select * from rev;,因為資料量比較小,第一次select之後,記錄就從data file快取到buffer cache,即使根據LRU演算法,負載不是太大的DB,很快的時間內這些資料還可能在其中,沒被age out,所以再次執行SQL時,就可能物理讀是0。
總結:
以上的示例就是@dbsnake講的“用合適的函式索引來避免看似無法避免的全表掃描“。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7192724/viewspace-773276/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 全表掃描和全索引掃描索引
- MySQL中的全表掃描和索引樹掃描MySql索引
- 全表掃描和全索引掃描繼續(PG-TiDB)索引TiDB
- [20210220]全索引掃描快速索引掃描的邏輯讀.txt索引
- [20190815]索引快速全掃描的成本.txt索引
- 索引掃描可能不如全表掃描的場景的理解__純粹資料量而言,不涉及CLUSTERING_FACTOR索引
- 【Oracle】 索引的掃描方式Oracle索引
- oracle是如何進行全表掃描的Oracle
- 怎麼解決因全表掃描帶來的 Buffer Pool 汙染
- [20180408]那些函式索引適合欄位的查詢.txt函式索引
- Win10系統下掃描器程式無法掃描的解決方法Win10
- go語言介面避免無意被適配Go
- 為什麼我們無法避免複雜?
- 如何避免表單的重複提交?
- 使用 RxJs Observable 來避免 Angular 應用中的 Promise 使用JSAngularPromise
- 24_Oracle資料庫全表掃描詳解(四)_全表掃描生產最佳化案例三則Oracle資料庫
- 避免對派生的非虛擬函式進行重定義函式
- PostgreSQL DBA(55) - MVCC#8(對全表掃描的影響)SQLMVCC#
- 技術分享 | 為什麼 SELECT 查詢選擇全表掃描,而不走索引?索引
- 儘量避免無知者無畏
- [20210219]全表掃描邏輯讀問題.txt
- 綜合掃描工具
- 避免修改建構函式輸入引數引起的 breaking change函式
- 實用知識】如何避免投標無效
- 索引設計(組合索引適用場景)索引
- 避免單例濫用單例
- 使用prometheus來避免Kubernetes CPU Limits造成的事故PrometheusMIT
- 掃描器的存在、奧普 掃描器
- AppBoxFuture: 二級索引及索引掃描查詢資料APP索引
- 關係型資料庫全表掃描分片詳解資料庫
- 23_Oracle資料庫全表掃描詳解(三)Oracle資料庫
- 22_Oracle資料庫全表掃描詳解(二)Oracle資料庫
- 21_Oracle資料庫全表掃描詳解(一)Oracle資料庫
- 用函式索引構造特殊的約束函式索引
- PostgreSQL技術內幕(七)索引掃描SQL索引
- jFinal避免表單重複提交
- java 表單避免重複提交?Java
- 如何避免SHRINKDATABASE & SHRINKFILE 產生索引碎片(轉載)Database索引
- TWAIN掃描識別控制元件:Web應用程式的掃描器SDKAI控制元件Web