Anti-explosion guardrail: estimate a join before you pay for it
The number of rows a join will produce can be computed ahead of time: the sum of the products of the per-key cardinalities. A threshold turns the estimate into a blocking guardrail.
Prerequisites
PySpark 3.x
Python
from pyspark.sql import functions as F
g = commandes.groupBy("ref").agg(F.count("*").alias("n_gauche"))
d = tarifs.groupBy("ref").agg(F.count("*").alias("n_droite"))
croise = g.join(d, "ref").withColumn(
"produit", F.col("n_gauche") * F.col("n_droite"))
estimation = croise.agg(F.sum("produit")).first()[0]
print(f"Jointure estimée : {estimation:,} lignes")
if estimation > 500_000_000:
croise.orderBy(F.desc("produit")).show(3)
raise RuntimeError("Explosion probable : cle 'ref' non unique des deux cotes")Result
Jointure estimée : 38,412,907,224 lignes +--------+--------+--------+--------------+ | ref|n_gauche|n_droite| produit| +--------+--------+--------+--------------+ |REF-MISC| 184,302| 208,114|38,355,826,428| |REF-0042| 1,204| 12| 14,448| |REF-1183| 880| 8| 7,040| +--------+--------+--------+--------------+ RuntimeError: Explosion probable : cle 'ref' non unique des deux cotes → REF-MISC est un fourre-tout présent 184 k × 208 k fois : 38 Md de lignes évitées
PySparkJointureCartésienGarde-fou