Masterclass Cheatsheet

Databricks PySpark
Tricks & Optimization

A definitive guide for Data Architects and Data Engineers to build high-performance Lakehouse architectures.

50+
Optimization Patterns
Delta
Deep Integration
CBO
Query Tuning
1 / 6 β€’ databricks-pyspark-optimization-v1.0
Section 01 & 02

Core Concepts & Cluster Setup

Foundations for reliable performance and engine configuration.

Architecture & Setup
πŸ“¦

Delta Format

Industry standard format for high performance and reliability on Databricks.

df.write.format('delta').save(path)
🌊

Delta Lake

Open-source layer adding ACID transactions and time travel to object storage.

spark.read.format('delta').load(path)
πŸ’ 

Liquid Clustering

Modern dynamic clustering that replaces complex manual partitioning.

CREATE TABLE t CLUSTER BY (id)
πŸ”„

Idempotencia

Design logic to ensure re-runs produce identical results without duplicates.

MERGE INTO t USING src ON t.id=src.id
πŸ…

Medallion Arch

Data flow pattern: Bronze (Raw) β†’ Silver (Clean) β†’ Gold (Aggregated).

spark.read.format('delta') .load('/bronze/events') .filter(...) .write.format('delta') .save('/silver/events')
πŸš€

Photon Engine

Native vectorized execution engine written in C++ for maximum throughput.

spark.conf.set('spark.databricks .photon.enabled', 'true')
βš–οΈ

Autoscaling

Dynamically adjust worker nodes based on workload. Min: 2, Max: 10.

"autoscale": {"min_workers": 2, "max_workers": 10}
⏱️

Job Clusters

Short-lived clusters dedicated to a single task. Saves cost vs Shared.

{"job_cluster_key": "etl_cluster", "new_cluster": { "spark_version": "14.3.x-scala2.12", "node_type_id": "Standard_DS3_v2"}}
πŸ“‘

Processing Time

Determines micro-batch frequency in structured streaming.

.trigger(processingTime='10s')
⚑

AvailableNow

Process all data currently available as a single batch in a stream.

.trigger(availableNow=True)
πŸ“

Checkpointing

Stores progress metadata to ensure fault tolerance in streaming.

.option('checkpointLocation', p)
πŸ“₯

Auto Loader

Efficiently ingests millions of files from cloud storage incrementally.

spark.readStream .format('cloudFiles') .option('cloudFiles.format', 'json') .load('/mnt/landing/events')
Section 03, 04 & 05

Queries & Aggregations

Manipulating and retrieving data with maximum efficiency.

Optimization & CRUD
🀝

MERGE INTO

Perform inserts, updates, and deletes in a single atomic operation.

MERGE INTO target t USING source s ON t.id = s.id WHEN MATCHED THEN UPDATE SET * WHEN NOT MATCHED THEN INSERT *
🧬

Schema Evolution

Automate table schema updates during data ingestion.

.option('mergeSchema', 'true')
πŸ•’

Watermarking

Manage state and late data arrival in streaming joins/aggs.

.withWatermark('ts', '10 min')
🧹

DeduplicaciΓ³n

Drop duplicate records efficiently in streaming pipelines.

df.dropDuplicates(['id'])
βœ‚οΈ

Column Pruning

Only select columns you need to reduce memory and I/O footprint.

# βœ… Good: select only needed cols df.select('id', 'city', 'amount') # ❌ Bad: reads all columns df.select('*')
🏹

Predicate Pushdown

Filters are applied at the source level before data hits the engine.

df.filter(col('year') == 2024)
🚫

Avoid UDFs

User Defined Functions are black boxes to Spark. Prefer native functions.

F.upper(col('name')) # not udf()
🧩

Partitioning

Physical layout based on a column to optimize query pruning.

df.write.format('delta') .partitionBy('year', 'month') .mode('overwrite') .save('/delta/sales')
πŸ§‚

Skew Handling

Salt keys to distribute unbalanced data across all partitions.

(col('id') + (rand()*10) .cast('int')).alias('salted_id')
πŸ’‘

Skew Hints

Manually inform Spark about skewed columns for better join plans.

SELECT /*+ SKEW('orders', 'user_id', (1001, 1002)) */ * FROM orders JOIN users ON orders.user_id = users.id
⚑

Dynamic Pruning

Filters data based on runtime results from other tables in a join.

SET spark.sql.optimizer .dynamicPartitionPruning=true
Section 06 & 07

Performance Tuning & Maintenance

Optimizing the physical storage and operational health of tables.

Tuning & Ops
πŸ› οΈ

OPTIMIZE

Compacts small files into larger, more efficient 1GB files.

OPTIMIZE sales_data
πŸŒ€

ZORDER BY

Multidimensional clustering to speed up selective search queries.

OPTIMIZE t ZORDER BY (id)
πŸ’Ύ

CACHE TABLE

Pulls table data into cluster RAM for frequent access.

CACHE TABLE temp_view
πŸ”€

Shuffle Partitions

Controls parallelism for wide operations. Crucial for cluster balance.

SET spark.sql.shuffle.partitions=200
🧱

REPARTITION

Forces a full shuffle to redistribute data across N partitions.

df.repartition(100)
πŸ“‰

COALESCE

Reduces partition count without a full shuffle (efficiency gain).

df.coalesce(10)
πŸ“’

BROADCAST JOIN

Sends small tables to every worker to avoid expensive shuffles.

/*+ BROADCAST(small_df) */
βš™οΈ

AQE

Adaptive Query Execution optimizes plans based on runtime stats.

SET spark.sql.adaptive.enabled=true
πŸ—‘οΈ

VACUUM

Deletes old file versions no longer needed for time travel.

VACUUM t RETAIN 168 HOURS
πŸ“œ

DESCRIBE HISTORY

Audit log of all changes made to a Delta table (Who, What, When).

DESCRIBE HISTORY sales_data
πŸ“Š

ANALYZE TABLE

Compute column stats for the Cost-Based Optimizer (CBO).

ANALYZE TABLE t COMPUTE STATS
πŸ’°

Spot Instances

Use spare cloud capacity for worker nodes to cut costs by ~70%.

"azure_attributes": { "availability": "SPOT_WITH_FALLBACK", "spot_bid_max_price": -1 } // -1 = on-demand price cap
Section 08 & 09

Advanced Tools & Architecture

Monitoring and long-term data design strategies.

Observability & Arch
✨

AUTO OPTIMIZE

Automatically optimizes file sizes during write operations.

delta.autoOptimize.optimizeWrite = true
πŸ“

File Size Tuning

Set the target size for data files. Ideal: 128MB to 1GB.

delta.targetFileSize = 134217728
πŸ”—

CLUSTER BY

Column definition for Liquid Clustering to replace partitioning.

ALTER TABLE t CLUSTER BY (region, date)
πŸ–₯️

Spark UI

Crucial for debugging DAGs, data skew, and shuffle spills.

# Get URL from notebook print(spark.sparkContext.uiWebUrl) # Or enable programmatically spark.conf.set( 'spark.ui.enabled', 'true')
πŸ”„

Workflows

Native orchestration to schedule and monitor multi-task jobs.

# Trigger via CLI databricks jobs run-now --job-id 123 # Or REST API curl -X POST $HOST/api/2.1/jobs/run-now -d '{"job_id": 123}'
πŸ“ˆ

Incremental Load

Only process new data. Efficient for both batch and streaming.

spark.readStream.format('delta') .load(path)
πŸ”“

Decoupled Layout

Separate physical storage optimization from logical structure.

# Physical: compact files independently OPTIMIZE silver.events ZORDER BY (ts) # Logical: query unchanged SELECT * FROM silver.events WHERE date = '2024-01-01'
⚑

DELTA CACHE

Transparent caching on worker SSDs for lightning fast reads.

spark.conf.set('spark.databricks .io.cache.enabled', 'true')
Final Summary

Checklist & Strategic Overview

Consolidated wisdom for reliable production data engineering.

Summary & Best Practices
⚑

Quick Tips

Scale logic, then hardware: Optimize transformation steps before increasing worker SKU.

Data layout is performance: Use ZORDER and Liquid to reduce scan overhead.

Incremental > Batch: Avoid re-processing entire tables unless logically required.

Always Measure: Use Spark UI to detect shuffles and data spills early.

βœ…

Best Practices

Use Delta Lake default: Ensure every table leverages ACID and time travel.

Automate Maintenance: Schedule OPTIMIZE and VACUUM tasks.

Job Clusters Only: Use ephemeral clusters for production workflows to save cost.

Design Idempotency: Every pipeline must be safely retry-able without corruption.

⚠️

Common Mistakes

Blind Scaling: Adding workers to fix bad code just hides the bottleneck (shuffle/skew).

OLTP Logic: Thinking row-by-row instead of set-based vectorized operations.

No Checkpoints: Forgetting checkpoints leads to state loss in streaming failures.

Over-partitioning: Creating too many small folders for small tables slows down listing.