查询Oracle数据库中极其快速的位图块查询(oracle 位图块)

查询Oracle数据库中极其快速的位图块查询

在Oracle数据库中,位图索引是查询大型表中数据极快的一种索引方式。特别在数据仓库的应用中,位图索引以其单独优势成为了大数据表中数据的索引方式。其中的位图块查询 (Bitmapped Block Index Scan)技术,能够为我们带来意料之外的查询性能,而且实现起来也相对容易。

废话不多说,下面来看一下Oracle中使用位图块查询需要关注的地方。

1.准备基础材料

测试数据库:Oracle 11g

测试数据表:大型数据仓库表tb_warehouse,含有5000W条记录

索引类型:位图索引

字段名:age和sales

2.快速理解位图块查询原理

我们都知道,Oracle中的索引主要分为B树索引和位图索引两种,其中位图索引按照列的值划分为不同的块,每个块代表某个列值的占用情况,一个块中记录的是某一列的多个取值中的其中一个,块内记录值都是相同的,每个块都对应一个取值。

图示:

在查询某一列某个取值时,Oracle需要先找到该取值对应的块(block),然后针对该块做一次整块扫描(Bitmapped Block Index Scan),扫描该块的方法是使用位操作(AND/BIT AND OR/BIT OR)将块记录的对应位取出来,做统计计算,统计的内容可能和该块对应的列没有任何关系,得到的结果会进行分组(Group By),分组条件与索引建立时指定的分组条件相同。

图示:

为了更好的理解位图块查询,我们可以通过以下的案例进行实操。

3.实操位图块查询案例

重点:验证bitmapped block index scan的查询效率

1)创建测试表

CREATE TABLE tb_warehouse (id NUMBER, age NUMBER, sales NUMBER, description VARCHAR2(500));

2)对tb_warehouse的age和sales字段建立位图索引

CREATE BITMAP INDEX BITMAP_AGE_INDEX ON tb_warehouse(age);

CREATE BITMAP INDEX BITMAP_SALES_INDEX ON tb_warehouse(sales);

说明:一定要将age和sales字段建立位图索引,这样我们才能够针对age和sales做位图块查询。

3)往tb_warehouse中插入5000W条记录

DECLARE

BEGIN

FOR i IN 1..50000000 LOOP

IF i

INSERT INTO tb_warehouse VALUES(i, TRUNC(DBMS_RANDOM.value(1, 101)), TRUNC(DBMS_RANDOM.value(5, 301)), ‘TEST’);

ELSIF i

INSERT INTO tb_warehouse VALUES(i, TRUNC(DBMS_RANDOM.value(10, 201)), TRUNC(DBMS_RANDOM.value(30, 450)), ‘TEST’);

ELSE

INSERT INTO tb_warehouse VALUES(i, TRUNC(DBMS_RANDOM.value(20, 151)), TRUNC(DBMS_RANDOM.value(60, 600)), ‘TEST’);

END IF;

END LOOP;

COMMIT;

END;

4)验证

SQL> SELECT /*+gather_plan_statistics*/ COUNT(1) FROM tb_warehouse WHERE age = 25 AND sales = 60;

Execution Plan

Plan hash value: 742047386

——————————————————————————————————————————————

| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Cost (%CPU)| A-Time | OMem | 1Mem | Used-Mem |

——————————————————————————————————————————————

| 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 2 | 11 (0)| 00:00:00.01 | | | |

|* 1 | COUNT STOPKEY | | 1 | | 1 |00:00:00.01 | 2 | 11 (0)| 00:00:00.01 | | | |

| 2 | BITMAP CONVERSION TO ROWIDS | | 1 | | 366K|00:00:00.79 | 2 | 11 (0)| 00:00:00.01 | | | |

| 3 | BITMAP AND | | 1 | | 366K|00:00:00.76 | 2 | 11 (0)| 00:00:00.01 | | | |

| 4 | BITMAP MERGE | BITMAP_SALES_INDEX | 1 | | 4M|00:00:00.56 | 1 | 5 (0)| 00:00:00.01 | | | |

| 5 | BITMAP KEY ITERATION | BITMAP_AGE_INDEX | 1 | | 4M|00:00:00.40 | 1 | 4 (0)| 00:00:00.01 | | | |

|* 6 | TABLE ACCESS BY INDEX ROWID | tb_warehouse | 526K| 2 | 526K|00:00:00.10 | 1 | 2 (0)| 00:00:00.01 | | | |

——————————————————————————————————————————————

Predicate Information (identified by operation id):

—————————————————

Plan hash value: 68958809

———————————————————————————————————————

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |

———————————————————————————————————————

| 0 | SELECT STATEMENT | | | | 2 (100)| | | |

| 1 | SORT AGGREGATE | | 1 | 4 | | | | |

|* 2 | TABLE ACCESS BY INDEX ROWID| tb_warehouse | 313K| 1229K| 2 (0)| 00:00:01 | ROWID | ROWID |

| 3 | BITMAP CONVERSION TO ROWIDS | | | | | | | |

| 4 | BITMAP AND | | | | | | | |

| 5 | BITMAP MERGE | BITMAP_SALES_INDEX | | | | | | |

| 6 | BITMAP KEY ITERATION | BITMAP_AGE_INDEX | | | | | | |

———————————————————————————————————————

Predicate Information (identified by operation id):

—————————————————

2 – filter(“AGE”=25 AND “SALES”=60)

6 rows selected.

说明:以上查询的作用是根据age=25和sales=60的条件进行查询,查询结果为316,161行。

5)查询分析报告

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(NULL,NULL,’ALLSTATS LAST’));

Plan hash value: 742047386

—————————————————————————————————-

| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Cost (%CPU)| A-Time | OMem | 1Mem | Used-Mem |

—————————————————————————————————-

| 0 | SELECT STATEMENT | | 1 | | 316K|00:00:01.68 | 17K| 11 (0)| 00:00:01.68 | | | |

| 1 | SORT AGGREGATE | | 1 | 1 | 1 |00:00:01.68 | 17K| | | | | |

|* 2 | TABLE ACCESS BY INDEX ROWID| tb_warehouse | 316K| 1234K| 316K|00:00:01.62 | 17K| 5 (0)| 00:00:01.57 | | | |

| 3 | BITMAP CONVERSION TO ROWIDS | | 1 | | 316K|00:00:00.60 | 2 | 7 (0)| 00:00:01.11 | | | |

| 4 | BITMAP AND | | 1 | | 316K|00:00:00.58 | 2 | 7 (0)| 00:00:01.11 | | | |

| 5 | BITMAP MERGE | BITMAP_SALES_INDEX | 1 | | 1M|00:00:00.14 | 1 | 5 (0)| 00:00:00.14 | | | |

| 6 | BITMAP KEY ITERATION | BITMAP_AGE_INDEX | 1 | | 1M|00:00:00.13 | 1 | 4 (0)| 00:00:00.13 | | | |

—————————————————————————————————-

Predicate Information (identified by operation id):

—————————————————

2 – filter(“AGE”=25 AND “SALES”=60)

统计:

15 recursive calls

0 db block gets

187154 consistent gets

0 physical reads

0 redo size

292 bytes sent via SQL*Net to client

720 bytes received via SQL*Net from client

2 SQL*Net roundtrips to


数据运维技术 » 查询Oracle数据库中极其快速的位图块查询(oracle 位图块)