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