如何优化 Impala 查询以将 LIKE 与 IN 结合(字面意思或有效)?
Posted
技术标签:
【中文标题】如何优化 Impala 查询以将 LIKE 与 IN 结合(字面意思或有效)?【英文标题】:How to optimize Impala query to combine LIKE with IN (literally or effectively)? 【发布时间】:2021-09-07 14:29:34 【问题描述】:我需要尝试优化 Impala SQL 中的查询,该查询对大约 60 个不同的字符串进行部分字符串匹配,针对 50+ 十亿行数据库中的两列。这两列中的值是加密的,并且必须使用用户定义的函数(在 Java 中)进行解密才能进行部分字符串匹配。所以查询看起来像:
SELECT decrypt_function(column_A), decrypt_function(column_B) FROM myTable WHERE ((decrypt_function(column_A) LIKE '%' + partial_string_1 + '%') OR (decrypt_function(column_B) LIKE '%' + partial_string_1 + '%')) OR ((decrypt_function(column_A) LIKE '%' + partial_string_2 + '%') OR (decrypt_function(column_B) LIKE '%' + partial_string_2 + '%')) OR ... [up to partial_string_60]
我真正想做的是解密我要比较的两列值,每行一次,然后将该值与所有部分字符串进行比较,然后进入下一行等(550 亿行)。这有可能吗?在使用该变量对 60 个字符串中的每一个进行字符串比较之前,是否可以有一个子查询将解密的列值分配给一个变量?然后进入下一行...
或者是否可以进行其他优化?例如。使用'IN',所以... WHERE (decrypt_function(column_A) IN ('%' + partial_string_1 + '%', '%' + partial_string_2 + '%', ... , '%' + partial_string_60 + '%')) OR (decrypt_function(column_B) IN ('%' + partial_string_1 + '%', '%' + partial_string_2 + '%', ... , '%' + partial_string_60 + '%'))
谢谢
【问题讨论】:
【参考方案1】:使用子查询和 regexp_like 可以有许多与 OR (|
) 连接的模式,因此您可以在单个正则表达式中检查所有替代方案,但如果模式字符串太长,您可能需要拆分为多个函数调用:
select colA, ColB
from
(--decrypt in the subquery
SELECT decrypt_function(column_A) as colA, decrypt_function(column_B) as ColB
FROM myTable
) as s
where
--put most frequent substrings first in the regexp
regexp_like(ColA,'partial_string_1|partial_string_2|partial_string_3') --add more
OR
regexp_like(ColB,'partial_string_1|partial_string_2|partial_string_3')
在 Hive 中使用以下语法:
where ColA rlike 'partial_string_1|partial_string_2|partial_string_3'
OR ColB rlike 'partial_string_1|partial_string_2|partial_string_3'
【讨论】:
很好的答案,谢谢。所以看起来好像我在使用部分字符串时不需要指定 % 符号(就像我对 LIKE 所做的那样)? @AlexKerr 你不需要 %。正则表达式语法不同,可能更复杂。如果你想使用复杂的正则表达式,研究正则表达式,见regular-expressions.info/tutorial.html以上是关于如何优化 Impala 查询以将 LIKE 与 IN 结合(字面意思或有效)?的主要内容,如果未能解决你的问题,请参考以下文章
当 regexp_like 和 regexp_extract 工作正常时,Impala regexp_like 查询返回 null