Big Data Sql

By the end of this lesson you'll be able to run the same SQL you already know across terabytes and petabytes of data — using distributed engines like Hive, Spark SQL, and Presto/Trino, and the laptop-sized powerhouse DuckDB — and you'll know why columnar storage and partitioning make those queries fast.

Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.

Part of the free SQL course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

Imagine billions of these rows spread across thousands of files in a data lake, one folder per day. Every query in this lesson runs against this events shape — a tiny preview is shown here so you can picture the columns.

Big data just means data too large or fast for a single database to handle comfortably — so the work is spread across many machines. The good news: you query it with the SQL you already know.

A normal database (PostgreSQL, MySQL) runs your query on one machine . A distributed query engine splits the work across a cluster of machines that each scan part of the data, then combines the partial answers. You still write SELECT … GROUP BY … ; the engine handles the splitting.

The big four you'll meet: Apache Hive (SQL compiled into batch jobs over Hadoop — slow but bottomless), Spark SQL (the same idea but in memory, far faster for interactive work), Presto/Trino (a "federated" MPP engine — MPP = massively parallel processing — that can join across many different sources at once), and DuckDB (not distributed at all, but astonishingly fast on a single machine for files up to ~100 GB).

A single database is one librarian searching one library. A distributed engine is a thousand librarians, each searching one wing, then handing their slips to a head librarian who tallies the total. Same request ("how many books on SQL?"), wildly more shelves — and it finishes in about the same time because everyone works at once.

A traditional database stores data row by row : all of row 1's values together, then all of row 2's. That's perfect when you fetch whole records one at a time. Analytics is the opposite — you usually want one or two columns across millions of rows (e.g. SUM(amount) ).

Columnar formats like Parquet and ORC store all of one column's values together. So SUM(amount) reads only the amount column and skips the other 49 columns on disk. Columns also compress brilliantly (similar values sit next to each other), so files are smaller and faster to read.

An EXTERNAL table is a SQL definition layered over files that already exist in storage (HDFS, S3). Hive doesn't copy or own the data — it just describes the columns so you can query the files with SQL. Drop the table and the files stay.

Partitioning physically splits the data into folders by a column — here, one folder per event_date . When your WHERE filters on that column, the engine reads only the matching folders. That's partition pruning (a form of predicate pushdown : the filter is pushed down to the storage layer so unneeded data is never read). Filtering one day out of a year can mean scanning 1 folder instead of 365.

Fill in the blanks so the query prunes to a single day's folder and totals revenue per event_type . The expected result is in the comments so you can check yourself.

Spark SQL runs the same standard SQL but keeps data in memory across the cluster, which makes repeated, interactive queries far faster than Hive's batch jobs. You register your files as a temporary view once, then query them like any table — window functions, CTEs, and joins all work.

Notice APPROX_COUNT_DISTINCT : at billions of rows, an exact distinct count is expensive, so big-data engines offer fast approximate versions (a couple of percent error) that finish in a fraction of the time.

DuckDB is the "SQLite for analytics": a single embedded engine, no server, that reads CSV and Parquet files directly . There's no loading step — you point read_parquet('…') (or read_csv_auto('…') ) at a file or a wildcard of files and query them immediately.

Because Parquet is columnar, DuckDB reads only the columns your query touches — exactly the storage win from Section 2, now in one line on your laptop. For datasets up to ~100 GB it's often faster than spinning up a cluster, and it costs nothing to run.

One concept this time — name the DuckDB function that reads Parquet files, and the count function for the body.

Presto/Trino is a federated MPP engine: it can join data living in different systems in a single SQL statement — a Postgres table, files in a Hive lake, even a document store — without first copying everything into one place. You reference each source by a catalog.schema.table name.

When should distributed SQL beat a single database? When the data no longer fits (or no longer fits affordably ) on one machine, when it spans multiple systems, or when scans are so large that splitting them across a cluster finishes work a lone server never could. For everyday app data — frequent small reads and writes — a single relational database is still simpler, cheaper, and faster.

Q: Do I have to learn a new language for big data?

No — that's the whole point. Hive, Spark SQL, Presto/Trino, DuckDB, and BigQuery all speak standard SQL. Your SELECT … GROUP BY … JOIN skills transfer directly; only the execution engine changes.

Q: When should I use DuckDB instead of a cluster?

If your data fits on one machine (roughly up to ~100 GB of Parquet), DuckDB is usually faster, simpler, and free — no cluster to manage. Reach for Spark/Presto when the data outgrows a single node or spans many systems.

Q: What's the real difference between Parquet and CSV?

CSV is row-oriented text: every query reads every column and there's no compression. Parquet is columnar and compressed, so analytics read only the needed columns and far fewer bytes. For big-data SQL, prefer Parquet (or ORC).

No. They're built for big scans and aggregation, not single-row lookups or constant updates. Keep your transactional app on PostgreSQL/MySQL; use big-data SQL for the analytics on top of it.

Put it all together — a brief, a blank canvas, and the expected result in the comments. Write it, then run it in DuckDB (or any SQL playground with sample data) to confirm.

Practice quiz

What does an EXTERNAL table in Hive do?

  • Copies the files into Hive's own managed storage
  • Creates an in-memory cache of the data
  • Defines SQL columns over files that already exist in storage, without copying them
  • Encrypts the underlying files

Answer: Defines SQL columns over files that already exist in storage, without copying them. An external table points at files where they live; Hive never owns or copies the data.

What is partition pruning?

  • Filtering on the partition column so only matching folders are scanned
  • Deleting old partitions automatically
  • Compressing partitions into one file
  • Sorting partitions alphabetically

Answer: Filtering on the partition column so only matching folders are scanned. A WHERE on the partition column lets the engine read only the relevant folders, not the whole lake.

Why is columnar storage (Parquet/ORC) faster for analytics than row storage?

  • It stores every row twice for redundancy
  • It avoids using any disk
  • It is uncompressed for speed
  • A query reads only the columns it needs and skips the rest of the file

Answer: A query reads only the columns it needs and skips the rest of the file. Columnar formats store each column together, so SUM(amount) reads only that column.

How does Spark SQL typically differ from Apache Hive?

  • Spark cannot run standard SQL
  • Spark keeps data in memory across the cluster, far faster for interactive queries
  • Spark only works on a single machine
  • Spark requires no cluster at all

Answer: Spark keeps data in memory across the cluster, far faster for interactive queries. Spark SQL runs the same SQL but in memory, often 10-100x faster than Hive's batch jobs.

What is DuckDB best described as?

  • A single-node, server-less engine that reads Parquet/CSV files directly
  • A distributed cluster engine like Spark
  • A federated engine joining many databases
  • A row-oriented OLTP database

Answer: A single-node, server-less engine that reads Parquet/CSV files directly. DuckDB is the 'SQLite for analytics': no server, reads files directly, fast up to ~100GB.

Which DuckDB function reads Parquet files directly with no load step?

  • load_parquet('...')
  • import_parquet('...')
  • read_parquet('...')
  • open_parquet('...')

Answer: read_parquet('...'). read_parquet (and read_csv_auto for CSV) query files directly without a CREATE TABLE step.

What makes Presto/Trino a 'federated' engine?

  • It only queries a single Postgres database
  • It can join data from different systems in one SQL statement
  • It stores all data in memory permanently
  • It converts SQL to MapReduce only

Answer: It can join data from different systems in one SQL statement. Trino is a federated MPP engine that joins across sources via catalog.schema.table names.

Why use APPROX_COUNT_DISTINCT instead of COUNT(DISTINCT ...) at scale?

  • It is always exact and free
  • It only works on partitioned tables
  • It removes the need for GROUP BY
  • An exact distinct count is expensive on billions of rows; the approximation is far faster

Answer: An exact distinct count is expensive on billions of rows; the approximation is far faster. Approximate distinct counts finish quickly with a couple of percent error, fine for big data.

What is the 'small-files problem' in Hive/Spark?

  • Files smaller than 1KB cannot be read at all
  • Thousands of tiny files cause huge per-file overhead and slow queries
  • Small files use too much memory in DuckDB
  • It is a bug in Parquet compression

Answer: Thousands of tiny files cause huge per-file overhead and slow queries. Tiny files cripple Hive/Spark; compact them into fewer, larger files (~128MB+).

When is a single relational database still the better choice over distributed SQL?

  • For scanning petabytes of analytics data
  • For joining across many separate systems
  • For everyday OLTP: frequent small reads and writes of whole records
  • Never; distributed SQL is always better

Answer: For everyday OLTP: frequent small reads and writes of whole records. Big-data engines are built for big scans, not single-row lookups or constant updates.