暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 使用多个函数索引或预先计算的json对象进行部分索引

ASKTOM 2020-05-20
252

问题描述

我有一个带有状态标志的订单表,显示该订单是否已完成。表中的大多数订单已完成: 可能只有5% ish的表是不完整的。
我知道我可以通过使用基于函数的索引来构建部分索引,该索引根据状态标志的值返回订单id或null。这样,索引中只存储不完整的订单。这一切都很好。
我的问题是,如果我需要表中的许多其他列,并且只希望索引扫描以避免计划中的索引ROWID访问表,那么执行此操作的最佳方法是什么。假设我也想要客户id和产品id。这些值永远不会为空,所以如果我将它们添加到索引中,这意味着我不会以部分索引结束,因为空值将只为初始函数列添加,因为其他2列将始终具有值。所以我看到了基本的方法,不确定哪种方法更好。

1.我构建一个由一串函数组成的索引,所有函数都根据状态字段的值返回所需的值。
2.我保留第一列基于查看状态的函数,但我只构建了一个索引,该索引不用作谓词或过滤器的一部分,但实际上返回了一个较大的预计算json对象,该对象从索引中的第二个函数返回,并根据该函数中所有必需的值作为参数返回一个json对象,以及用于确定该函数是否返回null或json对象的状态标志。

或者也许有一种更好的方法来构建带有额外foelds的部分索引?

专家解答

第一个问题: 你真的need做任何花哨的事情?

在状态上有一个简单的索引,性能是否 “足够好”?

如果不是,则在以下位置建立一个简单的旧索引:

create index ...
  on ... ( status, customer, product );


应该获得仅索引扫描。这 “足够好” 吗?

如果以上内容真的太慢,我只会开始做一些更深奥的事情。

如果你真的需要一个只存储感兴趣行的瘦索引,那么我会:

-为已完成的行创建所有感兴趣的列返回null的虚拟列
-索引那些
-在查询中使用虚拟列:

create table t as 
  select level tid,
         case 
           when level > 9500 then 'TODO'
           else 'DONE'
         end status,
         mod ( level, 31 ) product_id, 
         mod ( level, 79 ) customer_id,
         rpad ( 'x', 100, 'x' ) stuff
  from   dual
  connect by level <= 10000;

alter table t 
  add (
    status_todo as ( case when status = 'TODO' then status end ),
    customer_todo as ( case when status = 'TODO' then customer_id end ),
    product_todo as ( case when status = 'TODO' then product_id end )
  );

create index i 
  on t ( status_todo, customer_todo, product_todo );
  
select num_rows from user_indexes
where  index_name = 'I';

NUM_ROWS   
        500 

set serveroutput off

select customer_todo, product_todo
from   t
where  status_todo = 'TODO';

select * 
from   table(dbms_xplan.display_cursor(format => 'BASIC LAST'));

---------------------------------                                          
| Id  | Operation        | Name |                                          
---------------------------------                                          
|   0 | SELECT STATEMENT |      |                                          
|   1 |  INDEX RANGE SCAN| I    |                                          
---------------------------------

文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论