Как оптимизировать запрос Impala для объединения LIKE с IN (буквально или эффективно)?

#sql #hive #hiveql #sql-like #impala

Вопрос:

Мне нужно попытаться оптимизировать запрос в 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]
 

Что я действительно хочу сделать, так это расшифровать два значения столбцов, с которыми я сравниваю, по одному разу для каждой строки, а затем сравнить это значение со всеми частичными строками, затем перейти к следующей строке и т. Д. (Для 55 миллиардов строк). Возможно ли это каким-то образом? Может ли существовать подзапрос, который присваивает расшифрованное значение столбца переменной, прежде чем использовать его для сравнения строк с каждой из 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 может иметь множество шаблонов, объединенных с ИЛИ ( | ), поэтому вы можете проверить все альтернативы в одном регулярном выражении, хотя вам может потребоваться разделить несколько вызовов функций, если строка шаблона слишком длинная:

 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')
 

В улье используйте этот синтаксис:

 where ColA rlike 'partial_string_1|partial_string_2|partial_string_3'
   OR ColB rlike 'partial_string_1|partial_string_2|partial_string_3'
 

Комментарии:

1. Отличный ответ, спасибо. Так что, похоже, мне не нужно указывать знак % при использовании частичных строк (как я делаю с LIKE) ?

2. @AlexKerr Вам не нужен %. синтаксис регулярных выражений отличается и может быть намного сложнее. Если вы хотите использовать сложные регулярные выражения, изучите регулярное выражение, см. regular-expressions.info/tutorial.html