上一篇文章《doris数据库操作数字遇到的问题》是第一弹,文章结尾提到过doris不支持with语句,其实是因为我自己没找到正确使用的方式导致的。昨天因为客户现场有一个解析SQL的接口提示异常,所以就开始了长路漫漫的排查之旅。不过首先承认及纠正一下自己的错误:
doris是支持with语法的!!!
doris是支持with语法的!!!
doris是支持with语法的!!!
1.先说说背景
客户现场有一套老的环境,有一个SQL可以正常执行,但导入到新环境后发现执行异常。现场的实施解决不了,就在群里反馈了这个问题,于是我把这个问题接手过来了。
这不接手还好,接手过来一看,好家伙,1000多行的SQL,各种with、case when、union和子查询,一看到这种SQL就没有动手的欲望了。因为对业务不懂,所以只能把SQL复制出来,把业务表导到开发环境一点点排查起来。
2.解决过程
2.1.分段执行方式
对于这种“又臭又长”的王妈妈裹脚,只能先采取最笨的方法:分段执行。这里发现并解决了一个doris自带函数名错误的问题:date_add被写成了dateadd,导致提示以下错误
所以只能全局搜索并替换了这个函数,再执行又发现了Unknown table的异常
又搜索了一下这个“表”名,发现是跟在with语句后面的别名。然后想起了开头的那篇文章,还是认为是因为doris不支持with语句导致的。于是度娘了一下,发现doris是支持with语法的。其实度娘里也只有AI智能回答提到是支持的,其他内容都没啥帮助,但具体怎么写又不明确。这下好了,要长脑子了,开始百撕不得其姐了(bushi)
2.2.灵光乍现
觉得解决无望的时候,发现AI智能回答的内容有点蹊跷
然后对比了下业务SQL
先试试将别名改成小写看看效果,虽然,但是,就这么水灵灵的,居然成功了,然成功了,成功了,功了,了......
至于为什么,是否跟大小写敏感有关啥的,暂时不去深究了。
2.3.程序执行遇新问题
还讲啥呢,直接把SQL复制到apifox里调用接口啊,自认为这下肯定成功把问题解决了,不出意外的话,还是出意外了
虽然对于这个异常是真的度娘不出一点解决方案了,但定位基本就是SQL语法问题。回想了以前解决这类问题的经验,暂时先定位到注释上,把注释先去掉试试。
2.4.解决方案及方案优化
删除注释后,成功是成功了,但一个SQL执行器不支持写注释,就跟写java代码不能带注释一样,写多了到后面谁还记得那么多这是干什么用的。所以问题不能这么一刀切的解决(不能像jin'mo政策一样,管理不好就一刀切了再说)
于是,试了下在注释--后添加空格是可行的,或者将单行注释--,替换为多行注释/*xxxx*/也是可行的。但我们又不能要求实施这么去改,只能想办法加强我们代码的健壮性和兼容性。于是在代码里加了个判断,如果有--时,就添加空格。
虽然这种不是完全之策,也需要要求开发人员写SQL时候需要使用换行等,但目前来说已经够用了。
2.5.最后的问题
你们以为问题全都解决了,皆大欢喜?不好意思,现实往往会给你一个大逼斗,再嘲笑你一番。毕竟有些坑埋在那里,暂时为止没遇到不代表不存在。像这种1000多行的SQL,执行效率能有多低可想而知,代码使用的是动态数据源,每次连接都会动态加载写好的配置,所以请看
其实就是连接超时,被掐了。找了一下动态创建数据源的代码,发现了这么一行代码
props.put("connectionProperties", "druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000;socketTimeout=3000;connectTimeout=1200");
修改后
props.put("connectionProperties", "druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000");
最终所有问题都解决掉了,只是这SQL的执行效率就真的低,现场执行的返回时间是1.6min,暂时这样吧