محافظ ضدانفجار: برآورد یک join قبل از پرداخت هزینهاش
تعداد ردیفهایی که یک join تولید میکنه رو میشه از قبل حساب کرد: جمع حاصلضرب کاردینالیتیها بهازای هر کلید. یک آستانه، این برآورد رو تبدیل میکنه به یک محافظ که جلوش رو میگیره.
کاربرد
جلوگیری از تولید ۴۰ میلیارد ردیف، فقط چون کلیدی که قرار بود یکتا باشه دیگه نیست.
پیشنیازها
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")نتیجه
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