Bitmap 索引 vs. B-tree 索引:如何选择以及何时使用?——2-5
——理解適當使用每個索引對性能的影響
Bitmap 索引 vs. B-tree 索引:如何選擇以及何時使用?——1-5
Bitmap 索引 vs. B-tree 索引:如何選擇以及何時使用?——2-5
Bitmap 索引 vs. B-tree 索引:如何選擇以及何時使用?——3-5
Bitmap 索引 vs. B-tree 索引:如何選擇以及何時使用?——4-5
Bitmap 索引 vs. B-tree 索引:如何選擇以及何時使用?——5-5
?
本文內容
- 比較索引
- 步驟 3A(TEST_NORMAL 表 EMPNO 列創建 Bitmap 索引,執行范圍查詢)
- 步驟 3B(TEST_NORMAL 表 EMPNO 列創建 B-tree 索引,執行范圍查詢)
- 步驟 4A(TEST_RANDOM 表 EMPNO 列創建 Bitmap 索引,執行范圍查詢)
- 步驟 4B(TEST_RANDOM 表 EMPNO 列創建 B-tree 索引,執行范圍查詢)
步驟 3A(在 TEST_NORMAL)
該步驟創建 Bitmap 索引(同步驟 1A)。我們已經知道索引大小(28MB)及其聚類系數(等于表的行數)。現在執行一些范圍謂詞謂詞查詢。
SQL> drop index normal_empno_idx; 索引已刪除。 SQL> create Bitmap index normal_empno_bmx on test_normal(empno); 索引已創建。 SQL> analyze table test_normal compute statistics for table for all indexes for all columns; 表已分析。 SQL> SQL> set autot traceonly SQL> select * from test_normal where empno between &range1 and &range2; 輸入 range1 的值: 1 輸入 range2 的值: 2300 原值 1: select * from test_normal where empno between &range1 and &range2 新值 1: select * from test_normal where empno between 1 and 2300 已選擇2300行。 執行計劃 ---------------------------------------------------------- Plan hash value: 641040856 ------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2299 | 85063 | 417 (0)| 00:00:06 | | 1 | TABLE ACCESS BY INDEX ROWID | TEST_NORMAL | 2299 | 85063 | 417 (0)| 00:00:06 | | 2 | BITMAP CONVERSION TO ROWIDS| | | | | | |* 3 | BITMAP INDEX RANGE SCAN | NORMAL_EMPNO_BMX | | | | | ------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("EMPNO">=1 AND "EMPNO"<=2300) 統計信息 ---------------------------------------------------------- 1 recursive calls 0 db block gets 331 consistent gets 0 physical reads 0 redo size 130220 bytes sent via SQL*Net to client 2202 bytes received via SQL*Net from client 155 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 2300 rows processed SQL>步驟 3B(在 TEST_NORMAL)
該步驟對 TEST_NORMAL 表 EMPNO 列使用 B-tree 索引,執行范圍謂詞查詢。
SQL> set autot off SQL> drop index normal_empno_bmx; ? 索引已刪除。 ? SQL> create index normal_empno_idx on test_normal(empno); ? 索引已創建。 ? SQL> analyze table test_normal compute statistics for table for all indexes for all indexed columns; ? 表已分析。 ? SQL> SQL> set autot traceonly SQL> select * from test_normal where empno between &range1 and &range2; 輸入 range1 的值: 1 輸入 range2 的值: 2300 原值 1: select * from test_normal where empno between &range1 and &range2 新值 1: select * from test_normal where empno between 1 and 2300 ? 已選擇2300行。 ? ? 執行計劃 ---------------------------------------------------------- Plan hash value: 1781697849 ? ------------------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 2299 | 85063 | 23 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST_NORMAL | 2299 | 85063 | 23 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | NORMAL_EMPNO_IDX | 2299 | | 8 (0)| 00:00:01 | ------------------------------------------------------------------------------------------------ ? Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("EMPNO">=1 AND "EMPNO"<=2300) ? ? 統計信息 ---------------------------------------------------------- 1 recursive calls 0 db block gets 329 consistent gets 0 physical reads 0 redo size 130220 bytes sent via SQL*Net to client 2202 bytes received via SQL*Net from client 155 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 2300 rows processed ? SQL>當輸入不同范圍查詢時,結果如下所示:
表 4 TEST_NORMAL 表 EMPNO 列利用 Bitmap 和 B-tree 索引執行范圍查詢比較
| Bitmap | B-tree | |||
| Consistent Reads | Physical Reads | EMPNO (Range) | Consistent Reads | Physical Reads |
| 331??? | 0 | 1-2300 | 329 | 0 |
| 285 | 0 | 8-1980 | 283 | 0 |
| 346 | 19 | 1850-4250 | 344 | 16 |
| 427 | 31 | 28888-31850 | 424 | 28 |
| 371 | 27 | 82900-85478 | 367 | 23 |
| 2157 | 149 | 984888-1000000 | 2139 | 35 |
如上表所示,兩個索引的 consistent gets 和 physical reads 值很接近。表最后一行查詢范圍 (984888-1000000) 返回了將近 15000 行。因此,當我們要求一個全表掃描時(指定優化器提示為 /*+ full(test_normal) */ ),consistent read 和 physical read 值分別為 7239 和 5663。
3A 和 3B 的演示,在 TEST_NORMAL 表執行范圍查詢時,優化器使用了 EMPNO 列上的相應索引,邏輯 IO 和物理 IO 只是稍有差異。
步驟 4A(在 TEST_RANDOM)
該步驟在 TEST_RANDOM 表 EMPNO 列使用 Bitmap 索引進行范圍查詢,檢查 consistent gets 和 physical reads 值。這里,你會看到聚類系數的影響。
SQL> drop index random_empno_idx; ? 索引已刪除。 ? SQL> create Bitmap index random_empno_bmx on test_random(empno); ? 索引已創建。 ? SQL> analyze table test_random compute statistics for table for all indexes for all indexed columns; ? 表已分析。 ? SQL> SQL> set autot traceonly SQL> select * from test_random where empno between &range1 and &range2; 輸入 range1 的值: 1 輸入 range2 的值: 2300 原值 1: select * from test_random where empno between &range1 and &range2 新值 1: select * from test_random where empno between 1 and 2300 ? 已選擇2300行。 ? ? 執行計劃 ---------------------------------------------------------- Plan hash value: 4105816815 ? ------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2299 | 89661 | 418 (1)| 00:00:06 | | 1 | TABLE ACCESS BY INDEX ROWID | TEST_RANDOM | 2299 | 89661 | 418 (1)| 00:00:06 | | 2 | BITMAP CONVERSION TO ROWIDS| | | | | | |* 3 | BITMAP INDEX RANGE SCAN | RANDOM_EMPNO_BMX | | | | | ------------------------------------------------------------------------------------------------- ? Predicate Information (identified by operation id): --------------------------------------------------- 3 - access("EMPNO">=1 AND "EMPNO"<=2300) ? ? 統計信息 ---------------------------------------------------------- 1 recursive calls 0 db block gets 2463 consistent gets 0 physical reads 0 redo size 130220 bytes sent via SQL*Net to client 2202 bytes received via SQL*Net from client 155 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 2300 rows processed ? SQL>步驟 4B(在 TEST_RANDOM)
該步驟在 TEST_RANDOM 表 EMPNO 列使用 B-tree 索引進行范圍查詢?;貞浺幌滤饕木垲愊禂捣浅=咏碇行袛?#xff08;因此,不會很有效)。下面看看優化器是如何說的:
SQL> drop index random_empno_bmx; ? 索引已刪除。 ? SQL> create index random_empno_idx on test_random(empno); ? 索引已創建。 ? SQL> analyze table test_random compute statistics for table for all indexes for 2 all indexed columns; ? 表已分析。 ? SQL> SQL> select * from test_random where empno between &range1 and &range2; 輸入 range1 的值: 1 輸入 range2 的值: 2300 原值 1: select * from test_random where empno between &range1 and &range2 新值 1: select * from test_random where empno between 1 and 2300 ? 已選擇2300行。 ? ? 執行計劃 ---------------------------------------------------------- Plan hash value: 2650160170 ? --------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time --------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2299 | 89661 | 1740 (1)| 00:00:21| |* 1 | TABLE ACCESS FULL| TEST_RANDOM | 2299 | 89661 | 1740 (1)| 00:00:21| --------------------------------------------------------------------------------- ? Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("EMPNO"<=2300 AND "EMPNO">=1) ? ? 統計信息 ---------------------------------------------------------- 1 recursive calls 0 db block gets 6412 consistent gets 0 physical reads 0 redo size 121076 bytes sent via SQL*Net to client 2202 bytes received via SQL*Net from client 155 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 2300 rows processed ? SQL>由于聚類系數的原因,優化器選擇了全表掃描,而不是索引:
| Bitmap | B-tree | |||
| Consistent Reads | Physical Reads | EMPNO (Range) | Consistent Reads | Physical Reads |
| 2463??? | 1200 | 1-2300 | 6415 | 4910 |
| 2114 | 31 | 8-1980 | 6389 | 4910 |
| 2572 | 1135 | 1850-4250 | 6418 | 4909 |
| 3173 | 1620 | 28888-31850 | 6456 | 4909 |
| 2762 | 1358 | 82900-85478 | 6431 | 4909 |
| 7254 | 3329 | 984888-1000000 | 7254 | 4909 |
只有表最后一行,對 Bitmap 索引,優化器選擇了全表掃描,而對于所有的范圍查詢,對 B-tree 索引,優化器選擇全表掃描。這種差異是由于簇因素:當使用 bitmap 索引產生執行計劃時,優化器不考慮聚類系數的值,而對 B-tree 索引,則考慮。在這個場景,Bitmap 索引比 B-tree 索引更有效率。
4A 和 4B 的演示,在 TEST_RANDOM 表執行范圍查詢時,當索引時 Bitmap 索引時,優化器使用了;可當索引時 B-tree 索引時,優化器沒有使用,而是進行了全表掃描,邏輯 IO 和物理 IO 自然也就差異很大。
原因就在于 TEST_NORMAL 表是已組織的,而 TEST_RANDOM 表示無組織的。這就好像數據結構中的查找算法或排序算法,如果當前數組是已有序的,查找和排序會快很多。
下面步驟會揭示關于索引更有趣的事實。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的Bitmap 索引 vs. B-tree 索引:如何选择以及何时使用?——2-5的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Linux] shell
- 下一篇: 阿里云云服务器更新GCC是提示错误解决方