Оптимизация запросов Hadoop Hive

У меня есть таблица, разделенная по дате в формате ггггММдд. Если я сделаю простой запрос вроде этого:

SELECT COUNT(*) FROM MyTable WHERE Date >= '20140924'

затем он будет сканировать данные за 3 дня (сегодня 26-е). Однако я хотел бы, чтобы мой запрос всегда смотрел на последние 3 дня, поэтому я пишу его так:

SELECT COUNT(*) FROM MyTable
WHERE date >= from_unixtime(unix_timestamp() - 259200, 'yyyyMMdd')

Проблема в том, что теперь он сканирует каждый раздел. Есть ли способ заставить его предварительно вычислить часть запроса после большего?


person MikeKulls    schedule 26.09.2014    source источник


Ответы (2)


К сожалению, Hive не поддерживает это. Я сталкивался с подобной проблемой в прошлом, и в моей таблице кустов были разделы за последние 2 года.

Однако один обходной путь, который вы можете сделать, заключается в том, что вы можете запустить этот запрос куста внутри сценария оболочки, где вы будете вычислять эту дату в другой переменной и использовать ее в качестве переменной в запросе куста. Пример сценария:

#!/bin/bash

date=`date +"%Y%m%d" -d "-3 days"`
hive -e "select count(*) from MyTable where date >= '$date'"
person Amar    schedule 26.09.2014
comment
Я думаю, хотя это не идеально, это, вероятно, лучшее решение. Как правило, когда я писал sql в прошлом, он всегда вызывался из какого-то другого языка, где такие вещи легко сделать. Нет причин, по которым с ульем будет по-другому. - person MikeKulls; 29.09.2014
comment
также я пробовал разные другие вещи, чтобы сделать это в самом Hive, используя объединения и т. д., но на самом деле ничего не получилось .... поэтому, где все возможно использовать оболочку, я пытаюсь использовать ее для выполнения запросов - person Amar; 29.09.2014

Одним из обходных путей является создание таблицы с одной строкой, из которой вы можете выбрать расчетное время.

CREATE TABLE dual (dummy STRING);
INSERT INTO TABLE dual SELECT count(*) FROM dual;

SELECT COUNT(*) FROM MyTable t1
JOIN (
    SELECT from_unixtime(unix_timestamp() - 259200, 'yyyyMMdd') myDate
    FROM dual LIMIT 1
) t2 ON (t2.myDate = t1.Date)
person FuzzyTree    schedule 26.09.2014
comment
Я попробовал это, но он все равно сканировал каждый раздел. Может дело в версии? Я использую улей 0.12 - person MikeKulls; 29.09.2014
comment
@MikeKulls интересно, можете ли вы проверить, сканирует ли он все еще каждый раздел, если вы переместите дату в подзапрос, то есть SELECT COUNT(*) FROM MyTable WHERE date >= (select from_unixtime(unix_timestamp() - 259200, 'yyyyMMdd') from dual limit 1) - person FuzzyTree; 29.09.2014
comment
Я вообще не могу заставить это работать. Я получаю cannot recognize input near 'SELECT'. Я пробовал различные подзапросы, даже такие простые, как SELECT '20140926' AS DT FROM dual - person MikeKulls; 29.09.2014