Azure Databricks中Spark DataFrame重复行统计结果不一致求助
针对你遇到的count()返回1但collect()得到2条看似相同行、SQL分组无结果但直接查询出重复行的问题,可从以下几个方向排查:
1. 隐性列差异(最常见原因)
看似完全相同的两行,可能存在肉眼不可见的字符或数据类型差异:
查看原始列内容(含隐藏字符):
from pyspark.sql.functions import concat, lit df.where(col('name') == 'test').where(col('ftime') == '2022-07-18') \ .select([concat(col(c), lit('|')).alias(c) for c in df.columns]) \ .show(truncate=False)通过在列值后添加分隔符,可暴露空格、换行符、Unicode空白等隐藏字符。
校验行哈希值:
from pyspark.sql.functions import hash df.where(col('name') == 'test').where(col('ftime') == '2022-07-18') \ .select(hash(*df.columns).alias('row_hash')) \ .show()若两行哈希值不同,说明行数据存在真实差异。
检查列数据类型:
df.printSchema()确认
ftime是string还是date类型,若为date,可能存在日期格式转换时的隐性差异(比如原始数据是2022-07-18和2022/07/18,转换后显示相同但底层存储不同)。
2. 数据源读取重复
虽然原始JSON看起来只有一条记录,但读取逻辑可能导致重复加载:
直接查看原始文件内容:
dbutils.fs.head("/path/to/your/json/file")确认文件内是否真的只有一条记录,是否存在重复的JSON块。
检查JSON读取参数:
若读取时使用了multiLine=True,但JSON文件是单行格式,可能导致错误解析;反之,多行JSON未设置multiLine=True也可能出现问题。核对读取代码:# 示例:检查读取参数 df = spark.read.json("/path/to/file", multiLine=False)查看分区记录分布:
df.rdd.glom().map(len).collect()查看每个分区的记录数,确认是否某个分区存在重复数据。
3. 缓存或视图元数据问题
缓存的DataFrame或临时视图可能与实际数据不一致:
清除DataFrame缓存:
df.unpersist()重新执行
count()和collect()对比结果。重建临时视图:
DROP VIEW IF EXISTS df_referential;再重新创建视图后执行查询。
4. Spark统计信息优化导致的count()偏差
Spark的DataFrame count()可能依赖表的统计信息而非实际扫描数据,导致结果不准确:
强制扫描数据计算count:
df.where(col('name') == 'test').where(col('ftime') == '2022-07-18').rdd.count()RDD的
count()会实际执行全量扫描,对比DataFramecount()的结果。更新表统计信息:
%sql ANALYZE TABLE df_referential COMPUTE STATISTICS;更新后重新执行分组查询和count()。
内容的提问来源于stack exchange,提问作者Papotitu

