注册
从 SQL 玩转字符串匹配到优化分析
专栏/金的探索记录/ 文章详情 /

从 SQL 玩转字符串匹配到优化分析

2021/01/20 1829 1 0
摘要 从 SQL 玩转字符串匹配到优化分析

最近看到一个这样的面试题:

实现一个函数(使用 Java),输入一个数组,例如 1121121123115; 找到所有符合 A+B=C 模式的连续的值;例如 1+1=2; 112+3=115;

要求最终结果如下:

  • 1+1=2
  • 1+1=2
  • 1+1=2
  • 1+2=3
  • 12+11=23
  • 112+3=115

撇开 Java 和 PL/SQL 不看,毕竟也就是一个三重或者四重循环的事情,笔者手痒,希望能从 SQL 端入手,解决这个问题。

注:下文中测试用字符串为:112112112113224225123

笔者的 SQL 如下:

With tmp01 as(select '112112112113224225123' str from dual), Tmp02 as( Select str,level rn from tmp01 t1 connect by level<=length (str)) Select substr('112112112113224225123',t1.rn,t2.rn)||'+'|| substr('112112112113224225123',t1.rn+t2.rn,t3.rn)||'='|| substr('112112112113224225123',t1.rn+t2.rn+t3.rn,t4.rn) "a+b=c" from tmp02 t1,tmp02 t2,tmp02 t3,tmp02 t4 where substr('112112112113224225123',t1.rn,t2.rn)+ substr('112112112113224225123',t1.rn+t2.rn,t3.rn)= substr('112112112113224225123',t1.rn+t2.rn+t3.rn,t4.rn) and t1.rn+t2.rn+t3.rn+t4.rn<=length('112112112113224225123')+1;

思想是:借用字符串的长度,生成一个 1~length(str) 的结果集,然后利用这个结果集进行自连接,暴力破解出所有的组合可能性,满足 where 条件,也就是 A+B=C 这种情况的,我们筛选出来,这就是最终的结果。where 条件中的 t1.rn+t2.rn+t3.rn+t4.rn 是为了屏蔽 substr 函数中,截取长度不够的问题。

从分析和运行结果来看,功能是 ok 的,但是性能上似乎有点问题。当然,用 SQL 去解一些本应该程序做的事情,性能大多数时候都不会好到哪去。但是,在有限范围内,总会有人去无限优化,去接近极限值。下面就是 newkid 大叔的写法,他避免了第三次截取,只要结果集保证前两次截取剩下的字符串,正好可以满足前两次连续截取的字符串值的和的后缀 % 匹配,如第一次截取 1,第二次截取 2,剩下值是 3**********就满足了条件。

–newkid 进阶写法

注:在 DM 管理工具中执行时,请修改配置文件 COMPATIBLE_MODE=2。

with tmp01 as(select112112112113224225123’ str from dual), tmp02 as( select level rn from tmp01 t1 connect by level<=length(str)) select substr(‘112112112113224225123’,t1.rn,t2.rn)||+|| substr(‘112112112113224225123’,t1.rn+t2.rn,t3.rn)||=|| (substr(‘112112112113224225123’,t1.rn,t2.rn)+ Substr(‘112112112113224225123’,t1.rn+t2.rn,t3.rn)) “a+b=c” from tmp02 t1,tmp02 t2,tmp02 t3--,tmp02 t4 where substr(‘112112112113224225123’,t1.rn+t2.rn+t3.rn) like (substr(‘112112112113224225123’,t1.rn,t2.rn)+ Substr(‘112112112113224225123’,t1.rn+t2.rn,t3.rn))||&’;

注:以上 SQL 在 DM7.1.5.121版运行通过。

经过测试,后面的写法,性能提升 10~15 倍。

结论:建索引、看计划、考虑扫描方式是优化的常规方法,但是并非适用于所有场合,偶尔换个思路,跳出局限,或许效果会更好。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服