首页 > 解决方案 > Oracle 位置和索引

问题描述

我有这样的问题,这是我的数据结构

create table tab (
     id_tab integer not null,
     val1 integer,
     val2 integer,
     val3 integer,
     val4 integer,
     val5 integer,
     val6 integer,
     val7 integer,
     val8 integer,
     val9 integer,
     CONSTRAINT tab_pk PRIMARY KEY (id_tab)
  );
  
  create index val1_index on tab (val1);
  create index val2_index on tab (val2);
  create index val3_index on tab (val3);
  create index val4_index on tab (val4);
  create index val5_index on tab (val5);
  create index val6_index on tab (val6);
  create index val7_index on tab (val7);
  create index val8_index on tab (val8);
  create index val9_index on tab (val9);

  create procedure test1 as
  begin
    for x in 1..10000
    loop
      insert into tab(id_tab, val1, val2, val3, val4, val5, val6, val7, val8, val9)
      values ((select nvl(max(id_tab), 0) + 1 from tab), 
              decode(round(dbms_random.value(0,2)), 1, null, dbms_random.value(1,9)), 
              decode(round(dbms_random.value(0,2)), 1, null, dbms_random.value(1,9)), 
              decode(round(dbms_random.value(0,2)), 1, null, dbms_random.value(1,9)), 
              decode(round(dbms_random.value(0,2)), 1, null, dbms_random.value(1,9)), 
              decode(round(dbms_random.value(0,2)), 1, null, dbms_random.value(1,9)), 
              decode(round(dbms_random.value(0,2)), 1, null, dbms_random.value(1,9)),
              decode(round(dbms_random.value(0,2)), 1, null, dbms_random.value(1,9)), 
              decode(round(dbms_random.value(0,2)), 1, null, dbms_random.value(1,9)), 
              decode(round(dbms_random.value(0,2)), 1, null, dbms_random.value(1,9)));
    end loop;
  end;
  /

BEGIN
test1;
-- for my example, to find value:
insert into tab (id_tab, val1, val2, val3, val4, val5, val6, val7, val8, val9) 
values(-1, 3, 1, null, 5, 2, 1, 9, null, 1);
END;
/

现在我正在寻找结果

SELECT * FROM tab
where 
(decode(val1, 3, 1) = 1) and -- it's like: (val1 = 3 or (val1 is null and 3 is null) 
(decode(val2, 1, 1) = 1) and 
(decode(val3, null, 1) = 1) and -- it's like: (val1 = null or (val1 is null and null is null)
(decode(val4, 5, 1) = 1) and
(decode(val5, 2, 1) = 1) and
(decode(val6, 1, 1) = 1) and
(decode(val7, 9, 1) = 1) and
(decode(val8, null, 1) = 1) and
(decode(val9, 1, 1) = 1)

我有一个预期的结果:

在此处输入图像描述

问题是我有大约一百万来找到这样的组合,大约需要一个小时,问题是是否可以使用其他索引或以其他方式构建查询(在哪里)以使搜索这样的组合具有时间效率?

这是示例: https ://dbfiddle.uk/?rdbms=oracle_18&fiddle=ed77f058517197d4468e143f9deab3e1

DB:Oracle 11 标准版一

标签: oracleindexingwhere-clause

解决方案


如果在创建索引后使用函数,它将被该函数抑制并变得无用(就像这个(decode(val1, 3, 1) = 1))。另一方面,您不应该使用那么多索引。这不是最佳实践,您应该知道这一点。您创建的每个索引都会在磁盘上产生成本。

如果您坚持使用索引,您应该考虑创建一个函数来获取一些输入并根据您的条件对其进行解码,然后使用该函数创建您的索引。

基于函数的索引


推荐阅读