考虑以下场景。stupid_table
我无法控制的架构中有一个表 (a )。它是第三方,不受限制。没有敏感。我可以查询它,但不能添加索引或新表或更改设计。
中的每一列stupid_table
都是一个VARCHAR2(50 BYTE)
,有很多列,但我只需要其中两个:row_type
和magic_number
. magic_number
填充了整数的字符串表示形式,但仅设置为row_type
,'DATA'
我只需要大于零的幻数。
SELECT TO_NUMBER(magic_number)
FROM stupid_table
WHERE row_type = 'DATA'
AND TO_NUMBER(magic_number) > 0;
这会导致“无效数字”Oracle 错误,因为基于成本的优化器 (CBO) 选择TO_NUMBER
在检查之前评估row_type
并且有一大堆具有不同row_type
和不同用途的magic_number
字段的行。
好的,如果我先过滤行,然后进行比较呢?
SELECT TO_NUMBER(t.magic_number)
FROM (
SELECT magic_number
FROM stupid_table
WHERE row_type = 'DATA'
) t
AND TO_NUMBER(t.magic_number) > 0;
现在 CBO 似乎发现该查询非常简单,并且忽略了我使用的狡猾,产生了与原始查询计划相同的查询计划。
最后,无奈之下,我求助于肮脏的技巧:使用/*+RULE*/
查询提示强制 Oracle 使用旧的基于规则的优化器。这就像一个梦想,但它不应该是必要的,更不用说它正在使用不再支持的 Oracle 功能。
有一个更好的方法吗?