Почему время выполнения запроса SQL sql отличается между первым и вторым временем выполнения? - PullRequest
1 голос
/ 06 апреля 2019

Я использую spark sql для выполнения агрегированного запроса к источнику данных паркета.

Мой источник данных для паркета включает в себя таблицу со столбцами: id int, отметка времени time, location int, counter_1 long, counter_2 long, ..., counter_48. Общий объем данных составляет около 887 МБ.

Моя версия Spark 2.4.0. Я управляю одним ведущим и одним ведомым на одной машине (4 ядра, 16G памяти).

Используя spark-shell, я выполнил команду spark:

spark.time(spark.sql("SELECT location, sum(counter_1)+sum(counter_5)+sum(counter_10)+sum(counter_15)+sum(cou
nter_20)+sum(counter_25)+sum(counter_30)+sum(counter_35 )+sum(counter_40)+sum(counter_45) from parquet.`/home/hungp
han227/spark_data/counters` group by location").show())

Время выполнения 17 с.

Во второй раз я выполнил аналогичную команду (только изменение столбцов):

spark.time(spark.sql("SELECT location, sum(counter_2)+sum(counter_6)+sum(counter_11)+sum(counter_16)+sum(cou
nter_21)+sum(counter_26)+sum(counter_31)+sum(counter_36 )+sum(counter_41)+sum(counter_46) from parquet.`/home/hungp
han227/spark_data/counters` group by location").show())

Время выполнения составляет около 3 с.

Мой первый вопрос: Почему они разные? Я знаю, что это не кеширование данных из-за формата паркета. Это повторное использование чего-то вроде планирования запросов?

Я сделал еще один тест: первая команда

spark.time(spark.sql("SELECT location, sum(counter_1)+sum(counter_5)+sum(counter_10)+sum(counter_15)+sum(cou
nter_20)+sum(counter_25)+sum(counter_30)+sum(counter_35 )+sum(counter_40)+sum(counter_45) from parquet.`/home/hungp
han227/spark_data/counters` group by location").show())

Время выполнения 17 с.

Во второй команде я изменяю агрегатную функцию:

spark.time(spark.sql("SELECT location, avg(counter_1)+avg(counter_5)+avg(counter_10)+avg(counter_15)+avg(cou
nter_20)+avg(counter_25)+avg(counter_30)+avg(counter_35 )+avg(counter_40)+avg(counter_45) from parquet.`/home/hungp
han227/spark_data/counters` group by location").show())

Время выполнения составляет около 5 с.

Мой второй вопрос: Почему вторая команда быстрее первой, а разница во времени выполнения немного меньше, чем в первом сценарии?

Наконец, у меня есть проблема, связанная с приведенными выше сценариями: около 200 формул, таких как:

formula1 = sum(counter_1)+sum(counter_5)+sum(counter_10)+sum(counter_15)+sum(cou
nter_20)+sum(counter_25)+sum(counter_30)+sum(counter_35 )+sum(counter_40)+sum(counter_45)

formula2 = avg(counter_2)+avg(counter_5)+avg(counter_11)+avg(counter_15)+avg(cou
nter_21)+avg(counter_25)+avg(counter_31)+avg(counter_35 )+avg(counter_41)+avg(counter_45)

Мне нужно часто запускать следующий формат:

select formulaX,formulaY, ..., formulaZ from table where time > value1 and time < value2 and location in (value1, value 2...) group by location

Мой третий вопрос: Есть ли способ оптимизировать производительность (запрос, используемый один раз, должен быть быстрее, если он будет использован снова в будущем)? Спарк оптимизирует себя или мне нужно написать какой-то код, изменить конфигурацию?

1 Ответ

0 голосов
/ 07 апреля 2019

При выполнении агрегатной искры создаются так называемые случайные файлы. Если вы выполните один и тот же запрос дважды, он будет использовать файлы случайного воспроизведения, которые хранятся локально на рабочих файлах. К сожалению, вы не можете полагаться на них, чтобы они всегда были там, потому что в конечном итоге обработчик файлов получает gc'd. Если вы собираетесь выполнить 10 запросов для одного набора данных, кэшируйте его или используйте блоки данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...