Oracle压缩/ b-tree索引如何以及何时使用

时间:2018-01-29 12:43:40

标签: oracle database-indexes

我想将一个压缩索引添加到Oracle Applications工作流表hr.pqh_ss_transaction_history,以便访问特定类型的工作流(process_name)和特定人员的工作流(selected_person_id)。

虽然数据有偏差,但process_name中有很多重复值。但是,我想访问TFG_HR_NEW_HIRE_PLACE_JSP_PRCTFG_HR_TERMINATION_JSP_PRC流程类型。

"PROCESS_NAME","CNT"
"HR_GENERIC_APPROVAL_PRC",40347
"HR_PERSONAL_INFO_JSP_PRC",39284
"TFG_HR_NEW_HIRE_PLACE_JSP_PRC",18117
"TFG_HREMPSTS_TERMS_CHG_JSP_PRC",14076
"TFG_HR_TERMINATION_JSP_PRC",8764
"HR_ADV_INDIVIDUAL_COMP_PRC",4907
"TFG_HR_SIT_NOAPP",3979
"TFG_YE_TAX_PROV",2663
"HR_TERMINATION_JSP_PRC",1310
"HR_CHANGE_PAY_JSP_PRC",953
"TFG_HR_SIT_EXIT_JSP_PRC",797
"HR_SIT_JSP_PRC",630
"HR_QUALIFICATION_JSP_PRC",282
"HR_CAED_JSP_PRC",250
"TFG_HR_EMP_TERM_JSP_PRC",211
"PER_DOR_JSP_PRC",174
"HR_AWARD_JSP_PRC",101
"TFG_HR_SIT_REP_MOT",32
"TFG_HR_SIT_NEWPOS_NIB_JSP_PRC",30
"TFG_HR_SIT_NEWPOS_INBU_JSP_PRC",28
"HR_NEW_HIRE_PLACE_JSP_PRC",22
"HR_NEWHIRE_JSP_PRC",6

selected_person_id显然会更具选择性。不幸的是,此列有3774个空值,之后的最高计数为一个人为73。很多人只会有一排。总行数为136963。

我的查询将采用以下格式:

select psth.item_key,
       psth.creation_date,
       psth.last_update_date
from   hr.pqh_ss_transaction_history psth
where  nvl(psth.selected_person_id, :p_person_id) = :p_person_id
and    psth.process_name = 'HR_TERMINATION_JSP_PRC'
order  by psth.last_update_date

我使用的是Oracle 12c第1版。

我认为在selected_person_id上放置一个非压缩的b树索引是个好主意,因为返回的值将落在总行场景的不到5%的范围内,但是你如何处理当您使用nvl(psth.selected_person_id, :p_person_id) = :p_person_id选择时,列中的空值不会进入索引?是否有更有效的方法来编写sql以及如何创建此索引?

对于process_name我想使用压缩的b树索引。我假设声明是

CREATE INDEX idxname ON pqh_ss_transaction_history(process_name) COMPRESS 

rowid隐含的第二列。在这里使用rowid是否安全,因为通常不建议使用rowid?偏斜数据是一个问题(大多数时候我会在高容量方面选择)?我不明白压缩索引的效率如何。对于b-tree索引,您通常希望返回5%的数据,否则全表扫描实际上更有效。压缩索引如何返回这么多rowids,然后使用那些rowids查找整个表,比全表扫描更快?

或者,因为优化器只能使用两个索引中的一个,我是否应该创建一个基于未压缩函数的索引,selected_person_idprocess_name连接在一起?

1 个答案:

答案 0 :(得分:2)

也许你可以创建这个索引:

CREATE INDEX idxname ON pqh_ss_transaction_history
  (process_name, NVL(selected_person_id,-1)) COMPRESS 1

然后将您的查询更改为:

select psth.item_key,
       psth.creation_date,
       psth.last_update_date
from   hr.pqh_ss_transaction_history psth
where  nvl(psth.selected_person_id, -1) in (:p_person_id,-1)
and    psth.process_name = 'HR_TERMINATION_JSP_PRC'
order  by psth.last_update_date