类似查询的oracle索引

时间:2017-01-18 20:16:28

标签: oracle indexing

我在这里打击客户愚蠢/固执的案例。我们有一个申请按各种标准查找零售购物者。我们看到的最常见的变种是(部分)姓氏和(部分)邮政编码的组合。

当他们输入完整的邮政编码时,它的效果非常好。问题是他们有时会选择有效地输入像'3%'这样的邮政编码。

有什么奇迹可以克服我们的客户愚蠢?

ETA:这个特定的操作犬有两个表:客户和地址。我是一名DBA,参与支持这个应用程序,而不是开发方面。我没有能力改变代码(虽然我可以通过这种方式传递建议)但我在改进索引方面有一些余地。

客户有2200万行;地址有2300万。

“愚蠢”可能是一个严厉的词,但我不明白为什么你会试图通过邮政编码如“3%”来查找客户。我的意思是,输入他们的完整邮政编码或邮政编码付出了多少努力?

1 个答案:

答案 0 :(得分:1)

难点在于

WHERE postal_code LIKE '3%'
AND   last_name LIKE 'MC%'

通常只能从postal_code上的索引或last_name上的索引中受益。两者的复合索引没有帮助(超出前导列)。

将此视为可能的解决方案(假设您的表名为RETAIL_RECORDS

alter table retail_records 
  add postal_code_first_1 VARCHAR2(2) 
       GENERATED ALWAYS AS ( substr(postal_code, 1,1) );

alter table retail_records 
  add last_name_first_1 VARCHAR2(2) 
       GENERATED ALWAYS AS ( substr(last_name, 1,1) );

create index retail_records_n1 
  on retail_records ( postal_code_first_1, last_name_first_1, postal_code );

create index retail_records_n2 
  on retail_records ( postal_code_first_1, last_name_first_1, last_name );

然后,在为您提供postal_code和/或last_name条件的情况下,还要在相应的...first_1列中包含条件。

所以,

WHERE postal_code LIKE :p1
AND   last_name LIKE :p2
AND   postal_code_first_1 = SUBSTR(:p1,1,1)
AND   last_name_first_2 = SUBSTR(:p2,1,2)

平均而言,这将允许Oracle搜索1/260的数据。 (邮政编码的1/10和第一个字母的1/26)。好的,有很多姓氏以" M"开头。比起" Z",所以这有点慷慨。但即使对于高频组合(比如postal_code like '1%' and last_name like 'M%'),它仍然不应该查看超过1%的行。

我希望您在看到Oracle的基于成本的优化器实际上正在做的事情之后必须调整一下,但我认为这个想法的基本原则应该是合理的。