【问题标题】:Not able to use <> in Function based Indexes in Oracle无法在 Oracle 的基于函数的索引中使用 <>
【发布时间】:2015-03-20 07:56:34
【问题描述】:

我们正在尝试创建一个基于函数的索引,该索引在 where 子句中有 (不等于),但得到一个错误提示

ORA-00907: missing right parenthesis

使用 子句有什么问题吗?它可以以某种方式工作吗?

 CREATE INDEX IX_TEST_TABLE ON TEST_TABLE ((NVL(COL_A, 0) <> NVL(COL_B, 0));

【问题讨论】:

  • 您要索引什么查询?比较语句将返回布尔值的内部表示。 Oracle 不支持 SQL 中的布尔值,它们在索引中相对没用,因为只有 2 个值。
  • 您的索引表达式是一个不能被索引的布尔值。您需要在索引中包含一些“真实”列
  • 感谢宝贵的cmets
  • 我知道这与实际问题有所不同,但有没有办法获取 awr 中给出的 sql 查询的堆栈跟踪,我的意思是一种检查来自哪个包的查询流的方法或已触发的程序? tkprof 和 awr 都只显示 sql 和 elspased 时间,解析和获取。
  • @anudeepks - 您应该将其作为一个单独的问题提出。

标签: oracle plsql oracle11g


【解决方案1】:

您可以在 case 语句中使用该比较的结果来得出一个实际值,该值具有受支持的数据类型,而不是布尔值 - 已经注意到不支持 y Oracle 作为 SQL 数据类型.只要您始终如一,该值是什么并不重要。您可以使用 Y/N、0/1 等。

根据您的数据分布和查询方式的选择性,您可以使用位图索引:

create bitmap index ix_test_table on test_table
  (case when nvl(col_a, 0) <> nvl(col_b, 0) then 1 else 0 end);

然后当然是查询同一个case:

select * from test_table
where case when nvl(col_a, 0) <> nvl(col_b, 0) then 1 else 0 end = 1;
select * from test_table
where case when nvl(col_a, 0) <> nvl(col_b, 0) then 1 else 0 end = 0;

或者,如果它非常有选择性,则利用索引中不包含空值这一事实,仅包含您感兴趣的一小部分行:

create index ix_test_table on test_table
  (case when nvl(col_a, 0) <> nvl(col_b, 0) then 1 end);

select * from test_table
where case when nvl(col_a, 0) <> nvl(col_b, 0) then 1 end = 1;

您需要评估哪个适合您的数据。

【讨论】:

    【解决方案2】:

    在 Oracle 中,BOOLEAN 是一种仅限 PL/SQL 的类型,因此您不能在 SQL 中使用它,也不能在索引中使用。索引中的函数会导致 true 或 false,因此是不允许的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-05
      • 2013-03-24
      • 2017-06-23
      • 1970-01-01
      • 1970-01-01
      • 2015-12-05
      • 1970-01-01
      • 2016-02-09
      相关资源
      最近更新 更多