cancel
Showing results forย 
Search instead forย 
Did you mean:ย 
Data Engineering
Join discussions on data engineering best practices, architectures, and optimization strategies within the Databricks Community. Exchange insights and solutions with fellow data engineers.
cancel
Showing results forย 
Search instead forย 
Did you mean:ย 

Understanding Parquet File Storage for Large Datasets

gowri_databrick
New Contributor II

Hi everyone,

Iโ€™m learning about Parquet files and how they are used in Databricks for storing large datasets.

Iโ€™m trying to understand how column-based storage works in a practical situation.

For example, suppose an e-commerce company has 500 million order records containing customer details, product information, order dates, and payment information. If an analyst only needs order_date and order_amount to calculate daily sales, how does storing the data in Parquet help the system process this query efficiently?

Iโ€™d like to understand how Parquet storage works in this type of real-world scenario.

Thanks!

8 REPLIES 8

Satyasai
New Contributor II

Parquet's columnar architecture optimizes execution through three primary mechanisms: Column Projection, Page-Level Compression, and Metadata Pruning.
Row-Oriented vs. Column-Oriented Layout
To understand why Parquet is fast, compare how a traditional row-oriented format (like CSV or JSON) stores data on disk versus Parquet:
Row-Oriented Layout (CSV/JSON):
[Record 1: Customer, Product, Date, Amount, Payment] [Record 2: Customer, Product, Date, Amount, Payment] ...

Parquet Columnar Layout (Grouped into Row Groups):
[Row Group 1]
โ”œโ”€โ”€ Column 1 (order_date): [2026-09-01, 2026-09-01, 2026-09-02, ...]
โ”œโ”€โ”€ Column 2 (order_amount): [120.50, 45.00, 89.99, ...]
โ”œโ”€โ”€ Column 3 (customer_id): [C102, C994, C102, ...]
โ””โ”€โ”€ Column 4 (payment_info): [Visa, Mastercard, Amex, ...]
The 3 Core Performance Advantages in Practice
1. Column Projection (Reading Only What You Need)
In a CSV or JSON file, to read order_date and order_amount for 500 million rows, the query engine must scan every single byte of the file from start to finishโ€”including heavy text fields like customer addresses and payment tokensโ€”just to discard them in memory.
In Parquet, data for each column is stored sequentially in contiguous disk blocks.
โ€ข When Databricks executes SELECT order_date, order_amount FROM orders, the query engine performs Column Projection.
โ€ข It completely skips the byte locations on disk where customer_id, product_info, and payment_info reside.
โ€ข If those unused columns represent 80% of your row width, your total I/O drops by ~80% instantly.
2. Homogeneous Compression Ratios
Compression algorithms (like Snappy or ZSTD) perform best when repeating, similar patterns of data are adjacent to one another.
โ€ข Row-oriented files mix numbers, timestamps, long strings, and booleans together in every byte block, making high-ratio compression difficult.
โ€ข Parquet columns group identical data types together. An entire column block contains only dates (2026-09-01), or only floating-point amounts.
Parquet applies specialized encodings directly to column data before compressing:
โ€ข Dictionary Encoding: Replaces repeating text values with short integer keys.
โ€ข Run-Length Encoding (RLE): Stores repeated values efficiently (e.g., storing "2026-09-01 repeated 50,000 times" as a compact tuple).
This drastically reduces the physical footprint on cloud storage, allowing Databricks to pull much smaller files across the network.
3. Row Group Metadata & Data Skipping
A Parquet file is divided into Row Groups (typically containing 100,000 to 1,000,000 rows each). Every Parquet file contains a Footer with rich metadata.
For every Row Group, the Parquet footer records:
โ€ข Minimum and maximum values (min_val, max_val) for each column.
โ€ข Total null counts and physical byte offsets.
Parquet File Footer Metadata:
Row Group 1: order_date [Min: 2026-01-01, Max: 2026-03-31]
Row Group 2: order_date [Min: 2026-04-01, Max: 2026-06-30]
Row Group 3: order_date [Min: 2026-07-01, Max: 2026-09-30]
If your daily sales query includes a filter like WHERE order_date >= '2026-09-01', the Databricks engine reads the file footer first. It sees that Row Groups 1 and 2 contain no data for September 2026 and skips reading those row groups entirely.
Databricks Delta Lake Layer
While standard Parquet provides these column-level benefits, Delta Lake (the default table format in Databricks) builds an additional transaction log layer (_delta_log) on top of Parquet files. Delta Lake tracks file-level statistics across millions of Parquet files, enabling Databricks to skip entire files without even opening their footers.

 

balajij8
Esteemed Contributor II

@gowri_databrick 

Parquet's columnar storage organizes data by column rather than by row - all values for order_date are stored together, all order_amount values are stored together and so on. In your commerce scenario with 500 million records, when the analyst queries only order_date and order_amount, Databricks reads only those two columns from disk completely skipping the customer details, product information and payment data. This is fundamentally different from row-based formats like CSV or JSON where the entire row must be read even if you need just two fields. With Parquet, if those two columns represent only 10% of the total data width you are reading 90% less data from storage.

This columnar approach delivers three major benefits on Databricks - dramatically faster queries (reading 100MB instead of 1GB is a massive speed improvement), lower compute costs (less data to process leads to less CPU and memory usage) and reduced storage costs through great compression (values in a single column tend to be similar so order_date values like 2024-01-15 compress much better when stored together than scattered across row records). Query optimizer automatically leverages Parquet's column pruning and predicate pushdown, so filtering on order_date > 2024-01-01 reads only the relevant row groups making analytics on massive datasets fast and cost efficient.

@gowri_databrick 

Yes, this is a good example to understand why Parquet is useful.

In your scenario, imagine the 500 million order records are stored in Parquet with columns like:

customer_id | product_id | order_date | order_amount | payment_type

If the analyst runs:

SELECT order_date, SUM(order_amount)
FROM orders
GROUP BY order_date;

Databricks doesn't need to read all the columns such as customer_id, product_id, or payment_type.

Because Parquet stores data by column, Spark can mainly read just the order_date and order_amount columns needed for the query. This means less data is read from storage and less data needs to be processed.

For example, instead of reading the entire 500-million-row dataset with all 5 columns, Spark can focus on the two required columns.

So, the simple takeaway is:

Parquet โ†’ Column-based storage โ†’ Read only the required columns โ†’ Less I/O โ†’ Better query performance

data_pulse
New Contributor II

@gowri_databrick 

The easiest way to understand Parquetโ€™s column-based storage is with a small example:

order_id | customer | order_date | order_amount | payment
1        | Alice    | 2026-09-01 | 100          | Card
2        | Bob      | 2026-09-01 | 50           | Cash
3        | Carol    | 2026-09-02 | 300          | Card

In above dataset, row-orient formats like csv, the data is stored roughly as:

Row 1 โ†’ all columns
Row 2 โ†’ all columns
Row 3 โ†’ all columns

Parquet is organized into row groups, and within each row group the values are stored in separate column chunks:

order_id โ†’ 1, 2, 3
customer โ†’ Alice, Bob, Carol
order_date โ†’ 2026-09-01, 2026-09-01, 2026-09-02
order_amount โ†’ 100, 50, 300
payment โ†’ Card, Cash, Card

Now imagine the table has 500 million orders and the analyst runs queries like

SELECT order_date, SUM(order_amount)
FROM orders
GROUP BY order_date;

The query doesn't need customer, payment, product_id, etc. Because Parquet is columnar, the engine can mainly read the order_date and order_amount column chunks instead of reading all columns.

Benefit:

Row format: read a lot of unnecessary data โ†’ discard unused columns
Parquet:
read the columns the query actually needs.

Note: column pruning and data skipping are different things.

Column pruning โ†’ avoids reading unnecessary columns.
Data skipping โ†’ can avoid reading files/row groups that cannot contain the required rows, based on statistics.

So with a large Databricks table, the simplified flow is:

Find relevant files โ†’ skip irrelevant data โ†’ read only required columns โ†’ process the result.

Parquet itself provides the columnar file format, compression/encoding, row groups and statistics. Delta Lake adds the transaction log and file-level statistics/data skipping on top of those Parquet files.

Islam_hoti
New Contributor III

Hey ,

Parquet stores data column by column instead of row by row, so a query only reads the columns it asks for. If your table has 20 columns and the analyst needs just order date and order amount, Parquet reads those two and skips the rest. CSV would have to read all 500 million rows in full.

It also compresses much better, since values of the same type sit together, and it keeps min and max stats per column so Spark can skip entire chunks that do not match your filter.

Worth noting that Delta sits on top of Parquet and adds file level statistics, so on Databricks you usually want Delta rather than raw Parquet.

Coffee77
Honored Contributor III

Here is a summary on how parquet works in Databricks:

Coffee77_0-1788892868040.png

Besides you have here how traditional partitioning vs liquid clustering work:

Coffee77_1-1788893236605.png

I explain how it exactly works in this video but for now texts only in Spanish ...

 


Lifelong Solution Architect Learner | Coffee & Data

Khasim_1
New Contributor III

Hi Gowri,

The efficiency of Parquet in your e-commerce scenario comes down to two key architectural mechanisms: Columnar Projection and Data Skipping.

1. Columnar Projection (Reducing I/O): In a traditional row-based format (like CSV), the database must read the entire recordโ€”including customer details, product descriptions, and payment infoโ€”just to access the order_date and order_amount. That is a massive waste of I/O. Because Parquet is columnar, the engine physically only reads the files associated with the order_date and order_amount columns. It completely ignores the other columns on the disk, which reduces the amount of data read by potentially 80-90% in a wide table.

2. Data Skipping (Metadata Optimization): Parquet stores metadata (min/max values) at the file and row-group level. If your analyst filters by a specific date range, the Databricks engine reads the file metadata first. If the order_date range in a specific Parquet file doesn't match the query, the engine skips the file entirely. It never even opens it.

When we move to the Lakehouse, we often combine this with Delta Lake. With Delta, we add a transaction log on top of these Parquet files, which allows for Z-Ordering or Liquid Clustering. By co-locating similar data, we make that "data skipping" even more aggressive.

For your 500-million-record example, the difference is night and day: Row-based processing would be scanning terabytes, while Parquet/Delta allows you to scan only the necessary columns and skip irrelevant filesโ€”turning what would be a multi-minute job into a sub-second response.

Hope this helps!

 

Data Architect | 13 Years Domain Expertise | Databricks SA Champion Cohort

Coffee77
Honored Contributor III

In addition to my previous picture, I'd add the following explanation. In Databricks, Partition Pruning, Data Skipping and Parquetโ€™s columnar format work together to minimize I/O.

1. Partition Pruning โ†’ eliminates partitions.
If the table is partitioned by date and the query uses WHERE date = '2026-09-09', Databricks ignores all other partitions and their files. This step reduces largely from the very beginning the number of files (and data) to read.

2. Data Skipping โ†’ eliminates Parquet files.
Delta Lake uses file-level statistics such as min/max values to discard files that cannot contain the requested data. This is the second level to narrow data to read. 

3. Column Pruning โ†’ reads only required columns.
Parquet stores data by columns rather than by rows. Once the relevant files are selected, Databricks reads only the columns required by the query instead of the complete rows.

So, the flow would look like something similar to this: Query โ†’ Partition Pruning โ†’ Data Skipping โ†’ Parquet Files โ†’ Required Columns โ†’ Data

I hope it helps.


Lifelong Solution Architect Learner | Coffee & Data