我有一个包含300M行和50列的大型事实表。此表格有多个报告,每个报告仅使用表格中的50列中的几列。
事实表中的每一列都使用BITMAP INDEX
编制索引。我们的想法是将这些索引用作原始表的单列版本,假设oracle可以轻松地合并BITMAP INDEX
。
如果我在WHERE
语句中使用表中的几列,我可以看到oracle能够有效地合并这些索引。执行计划中有BITMAP AND
个操作符合预期。
如果我在SELECT
语句中使用表中的几列,我可以看到,根据列的选择性,oracle执行不需要的TABLE ACCESS
或BITMAP CONVERSION [to rowids]
,然后执行{{1}这些转换。
在加入多个HASH JOIN
时,有没有办法消除HASH JOIN
?当列出现在BITMAP INDEX
语句而不是BITMAP MERGE
时,oracle中是否有任何提示强制SELECT
?
考虑到WHERE
语句中确实不需要HASH JOIN
语句,BITMAP INDEX
SELECT
WHERE
SELECT a, b, c /* 3 BITMAP CONVERSIONs [to rowids] and then 2 unneeded HASH JOINS */
FROM fact;
SELECT a, b, c, d, e /* TABLE ACCESS [full] instead of reading all the data from indexes */
FROM fact;
SELECT a /* BITMAP INDEX [fast full scan] as expected*/
FROM fact
WHERE b = 1 and c = 2; /* BITMAP AND over two BITMAP INDEX [single value] as expected */
SELECT section, subsection
FROM table
WHERE id = :id
ORDER BY section, subsection
{{1}但我找不到任何证据表明甲骨文可以避免它。
以下是一些例子:
Array
(
[0] => Array
(
section, => 1
[0] => 1
subsection=> 1
[1] => 1
)
[1] => Array
(
section, => 1
[0] => 1
subsection=> 2
[1] => 2
)
)
是否有任何提示可以优化示例#1和#2?
在制作中我使用的是oracle11g,但我在oracle12c上尝试过类似的查询,看起来在两个版本的oracle中表现相同。
答案 0 :(得分:1)
经过一些研究后,如果有效地在BITMAP INDEX
子句中使用它们,oracle12c似乎无法加入SELECT
。
在BITMAP INDEX
子句中没有专用的访问路径来加入SELECT
es,因此在这种情况下使用HASH JOIN
。
在这种情况下,Oracle无法使用BITMAP MERGE
访问路径,因为它在两个位图之间执行OR
操作:
Bitmap Merge的工作原理 合并在两个位图之间使用
OR
操作。 生成的位图选择第一个位图中的所有行, 加上每个后续位图的所有行。
详细分析显示,在我的案例中,成本优化器仅考虑HASH JOIN
。我无法在BITMAP INDEX
声明中找到任何可以有效使用SELECT
es的证据。 Oracle documentation建议仅在BITMAP INDEX
子句中使用WHERE
es或将事实与维度相关联。
以下任何一种都属实:
- 索引列将在查询中受到限制(在
WHERE
条款)。或
- 索引列是维度表的外键。在这 例如,这样的指数将使星变换更有可能。
就我而言,这两者都不是。
答案 1 :(得分:0)
我认为你所看到的实际上是"索引加入访问路径"在行动:) Oracle需要从ROWID上的两次扫描中加入数据,将行拼接在一起。散列连接是对Oracle开放的唯一方法。您使用位图索引的事实实际上是无关紧要的;你看到与b树索引相同的行为
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1973K| 43M| 137K (30)| 00:00:06 |
| 1 | VIEW | index$_join$_001 | 1973K| 43M| 137K (30)| 00:00:06 |
|* 2 | HASH JOIN | | | | | |
|* 3 | INDEX FAST FULL SCAN| IO | 1973K| 43M| 17201 (78)| 00:00:01 |
|* 4 | INDEX FAST FULL SCAN| IT | 1973K| 43M| 17201 (78)| 00:00:01 |
-------------------------------------------------------------------------------------------