Есть два способа: либо статистика будет взята из metastore, для которой требуется запуск ANALYZE
заранее (сканирование по данным), либо статистика (на самом деле только SizeInBytes) будет оцениваться с использованием InMemoryFileIndex
, который не требует сканированияповерх данных, но используя Hadoop API Spark собирает размер каждого файла.
Какой из этих методов будет использоваться, зависит от дополнительных настроек. Например, если SizeInBytes
доступно в metastore, а CBO (оптимизация на основе затрат) включена с помощью параметра конфигурации
spark.cbo.enabled
, Spark получит его из metastore. Если CBO выключен (это значение по умолчанию в Spark 2.4), Spark будет использовать InMemoryFileIndex
. Если SizeInBytes
недоступен в metastore, Spark может использовать либо CatalogFileIndex
, либо InMemoryFileIndex
. CatalogFileIndex
будет использоваться, например, если ваша таблица разбита на разделы, а точнее, если это выполнено (взято непосредственно из исходного кода Spark):
val useCatalogFileIndex = sparkSession.sqlContext.conf.manageFilesourcePartitions && catalogTable.isDefined && catalogTable.get.tracksPartitionsInCatalog && catalogTable.get.partitionColumnNames.nonEmpty
В этом случае, если статистика не находится в metastore,Spark будет использовать defaultSizeInBytes
из конфигурации:
spark.sql.defaultSizeInBytes
, которая по умолчанию Long.MaxValue
, поэтому размер будет завышен до максимального значения. Я предполагаю, что это худший сценарий, статистика не в метастазах, но Spark ищет их там с помощью CatalogFileIndex, он не находит ее и поэтому использует очень большое нереалистичное значение.