STAR_TRANSFORMATION_ENABLED=TRUE生效需同时满足三个条件:参数设为TRUE、事实表外键列有位图索引、维度表连接列有主键或唯一约束。

STAR_TRANSFORMATION_ENABLED=TRUE 不等于星型转换就生效,三个硬性条件缺一不可。
为什么执行计划里看不到 STAR TRANSFORMATION?
常见错误现象是:明明在 SALES.CUST_ID 上建了位图索引,WHERE 也写了 CUSTOMERS.CUST_STATE_PROVINCE = 'CA',但 EXPLAIN PLAN 仍显示 TABLE ACCESS FULL on SALES——这不是索引没建对,而是优化器根本没走星型转换路径。
原因只有三个,少一个都不行:
-
STAR_TRANSFORMATION_ENABLED必须为TRUE(默认是FALSE) - 事实表外键列(如
SALES.CUST_ID)上必须有BITMAP INDEX(不是 B-tree,也不能建在维度表主键上) - 维度表连接列(如
CUSTOMERS.CUST_ID)必须有PRIMARY KEY或UNIQUE约束(仅靠NOT NULL不够)
怎么确认三个条件都满足?
逐项验证比猜更省时间:
- 查参数:
SHOW PARAMETER star_transformation_enabled,如果不是TRUE,执行ALTER SESSION SET STAR_TRANSFORMATION_ENABLED = TRUE(或改系统级参数) - 查维度表主键:
SELECT constraint_type FROM user_constraints WHERE table_name = 'CUSTOMERS' AND constraint_name = 'CUSTOMERS_PK',返回必须是P(PRIMARY KEY) - 查事实表索引:
SELECT index_type FROM user_indexes WHERE table_name = 'SALES' AND index_name = 'SALES_CUST_BIX',必须是BITMAP;且建法必须是CREATE BITMAP INDEX sales_cust_bix ON SALES(CUST_ID)
STAR TRANSFORMATION 对 SQL 写法有隐含要求
它不是万能重写器,只对“标准星型查询”敏感:
- JOIN 必须是等值连接(
ON f.cust_id = d.cust_id),不能带类型转换(如f.cust_id::text = d.cust_id::text) - 过滤条件必须落在维度表非主键列上(如
CUSTOMERS.CUST_STATE_PROVINCE = 'CA'),不能只在事实表或WHERE 1=1这类空条件 - 不能用
SELECT *或包含未参与 JOIN 的大字段(会抑制转换,改用明确列名) - 子查询谓词(如
s.cust_id IN (SELECT cust_id FROM customers WHERE ...))是转换后自动加的,你不用手写,但也不能干扰它——比如加/*+ NO_STAR_TRANSFORMATION */提示
执行计划里看到什么才算成功?
真正生效的标志不是“用了位图索引”,而是以下三项同时出现:
- Operation 列出现
STAR TRANSFORMATION(不是BITMAP MERGE单独出现) - 有多个
BITMAP INDEX SINGLE VALUE或BITMAP INDEX RANGE SCAN扫描维度表主键索引 - 事实表访问方式变成
BITMAP CONVERSION TO ROWIDS→TABLE ACCESS BY INDEX ROWID BATCHED,而非FULL
最容易被忽略的是:维度表主键约束和事实表位图索引必须在同一 schema 下、且统计信息要新鲜(DBMS_STATS.GATHER_TABLE_STATS 最好刚跑过),否则优化器可能因成本估算失真而弃用转换。











