#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