Best practices

  • Каждый вызов DROP добавляет этап в плане, поэтому лучше избегать множественного исключения колонок. Эффективнее использовать одиночный SELECT с нужным набором колонок;
  • использование операции LIMIT имеет свои особенности, влияющие на производительность. В Apache Spark она работает следующим образом: на каждой партиции выполняется стадия LocalLimit, её результат отправляется в shuffle и по всем собранным в shuffle результатам выполняется операция GlobalLimit. В случае использования limit(x).collect() или take(x) операция проходит в несколько итераций. Изначально количество участвующих партиций начинается с одной и с каждой итерацией умножается на значение параметра spark.sql.limit.scaleUpFactor (по умолчанию равно четырём). В случае использования операций count() или write.save("/output/path") операция LocalLimit выполняется на каждой партиции, и для больших датасетов с множеством партиций производительность limit ухудшается. Существует два варианта решения данной проблемы:
    • если значение limit является небольшим, таким, что результат выполнения take(x) помещается в памяти драйвера, можно использовать limitedDf = spark.createDataFrame(spark.sparkContext.parallelize(df.take(10000)), df.schema);
    • в качестве альтернативы операции LIMIT можно использовать TABLESAMPLE. Но если указывать TABLESAMPLE (x ROWS), то в плане выполнения такой вызов будет эквивалентен LIMIT x.
  • Для чтения данных, использующих Hive-совместимую схему партиционирования по директориям в Кипарисе, опция recursiveFileLookup должна явно быть выставлена в false: spark.read.option("recursiveFileLookup", "false"). В SPYT она по умолчанию выставлена в true для унификации с поведением YQL и CHYT.
Предыдущая
Следующая