Понимание данных, отсканированных при запросе ИЛИ C с помощью Presto / Athena - PullRequest
1 голос
/ 11 марта 2020

У меня большой объем данных в OR C файлах в AWS S3. Данные в файлах OR C сортируются по uuid . Я создаю таблицу AWS Athena (Presto) поверх них и запускаю следующий эксперимент.

Сначала я извлекаю первую строку, чтобы посмотреть, сколько данных сканируется:

select * from my_table limit 1

Этот запрос сообщает 18 МБ сканируемых данных.

Я записываю uuid из строки, возвращенной в первом запросе, и запускаю следующий запрос:

select * from my_table where uuid=<FIRST_ROW_UUID> limit 1

Этот запрос сообщает о 8,5 ГБ сканируемых данных.

В принципе оба запроса возвращают одинаковый результат, но второй запрос сканирует в 500 раз больше данных!

Есть идеи, почему это происходит? Это что-то присуще дизайну OR C или это c определяет, как Presto взаимодействует с S3?

[ПРАВИТЬ после ответа Илья-Кисила]

Давайте изменим последний запрос, чтобы выбрать только столбец uuid:

select uuid from my_table where uuid=<FIRST_ROW_UUID> limit 1

Для этого запроса количество проверенных данных падает примерно до 600 МБ ! Это означает, что основная часть 8,5 ГБ, отсканированных во втором запросе, связана со сбором значений из всех столбцов для найденной записи, а не с поиском этой записи.

Учитывая, что все значения в записи в сумме равны более 1 МБ, сканирование почти 8 ГБ данных для объединения этих значений кажется чрезмерным. Это похоже на некоторую особенность OR C или столбчатых форматов в целом, и мне интересно, существуют ли стандартные методы, например, свойства OR C, которые помогают уменьшить эти издержки?

1 Ответ

0 голосов
/ 11 марта 2020

Ну, это довольно просто. В самый первый раз ваш запрос выберет случайную запись из ваших данных. Кроме того, не гарантируется, что вы прочитали самую первую запись, поскольку файлы OR C разделяемы и могут обрабатываться параллельно. С другой стороны, второй запрос ищет указанную запись c.

Вот аналогия. Предположим, у вас есть 100 монет UUID и некоторая другая информация на их спинах. Все они лежат лицом вверх на столе, поэтому вы не можете видеть их UUID.

select * from my_table limit 1

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

select * from my_table where uuid=<FIRST_ROW_UUID> limit 1

Этот запрос похож на то, что вы хотите посмотреть информацию, написанную на обороте указанной c монеты. Вряд ли вы бы бросили правильную монету с первой попытки. Поэтому вам нужно будет «сканировать» больше монет (данных).

Один из распространенных способов уменьшить размер отсканированных данных - это разделить ваши данные, т.е. поместить их в отдельные «папки» (не файлы) в ваше ведро S3. Затем имена «папок» можно использовать в качестве виртуальных столбцов в определении таблицы, то есть дополнительных метаданных для вашей таблицы. Взгляните на этот пост , в котором более подробно рассказывается, как оптимизировать запросы в Афине.

...