我在这里打击客户愚蠢/固执的案例。我们有一个申请按各种标准查找零售购物者。我们看到的最常见的变种是(部分)姓氏和(部分)邮政编码的组合。
当他们输入完整的邮政编码时,它的效果非常好。问题是他们有时会选择有效地输入像'3%'
这样的邮政编码。
有什么奇迹可以克服我们的客户愚蠢?
ETA:这个特定的操作犬有两个表:客户和地址。我是一名DBA,参与支持这个应用程序,而不是开发方面。我没有能力改变代码(虽然我可以通过这种方式传递建议)但我在改进索引方面有一些余地。
客户有2200万行;地址有2300万。
“愚蠢”可能是一个严厉的词,但我不明白为什么你会试图通过邮政编码如“3%”来查找客户。我的意思是,输入他们的完整邮政编码或邮政编码付出了多少努力?
答案 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的基于成本的优化器实际上正在做的事情之后必须调整一下,但我认为这个想法的基本原则应该是合理的。