Пытаясь глубже понять, как работает spark, я играл с интерфейсом командной строки pyspark (2.4.0). Я искал разницу между использованием limit(n).show()
и show(n)
. В итоге я получил два очень разных времени выполнения для двух очень похожих запросов. Ниже приведены команды, которые я выполнил. Файл parquet, на который ссылается приведенный ниже код, содержит около 50 столбцов и имеет размер более 50 ГБ в удаленных HDFS.
# Create dataframe
>>> df = sqlContext.read.parquet('hdfs://hdfs.host/path/to.parquet') ↵
# Create test1 dataframe
>>> test1 = df.select('test_col') ↵
>>> test1.schema ↵
StructType(List(StructField(test_col,ArrayType(LongType,true),true)))
>>> test1.explain() ↵
== Physical Plan ==
*(1) Project [test_col#40]
+- *(1) FileScan parquet [test_col#40]
Batched: false,
Format: Parquet,
Location: InMemoryFileIndex[hdfs://hdfs.host/path/to.parquet],
PartitionCount: 25,
PartitionFilters: [],
PushedFilters: [],
ReadSchema: struct<test_col:array<bigint>>
# Create test2 dataframe
>>> test2 = df.select('test_col').limit(5) ↵
>>> test2.schema ↵
StructType(List(StructField(test_col,ArrayType(LongType,true),true)))
>>> test2.explain() ↵
== Physical Plan ==
CollectLimit 5
+- *(1) Project [test_col#40]
+- *(1) FileScan parquet [test_col#40]
Batched: false,
Format: Parquet,
Location: InMemoryFileIndex[hdfs://hdfs.host/path/to.parquet],
PartitionCount: 25,
PartitionFilters: [],
PushedFilters: [],
ReadSchema: struct<test_col:array<bigint>>
Обратите внимание, что физический план почти идентичен для обоих test1
и test2
. Единственным исключением является то, что план test2 начинается с "CollectLimit 5". После настройки этого я побежал test1.show(5)
и test2.show(5)
. Тест 1 вернул результаты мгновенно. Тест 2 показал индикатор выполнения задач 2010 года и занял около 20 минут (у меня был только один исполнитель).
Вопрос Почему тест 2 (с ограничением) показал такие плохие результаты по сравнению с тестом 1 (без ограничения)? Набор данных и набор результатов были идентичны, а физический план был почти идентичен.