Skip to content
intermediate Phase 37 · Database Fundamentals

Flat Tables in Magento

Understanding flat tables, catalog_product_flat, catalog_category_flat, and when they help performance

45m
0 problems
Topic Progress 0%

What Are Flat Tables?

Flat Tables vs EAV

Flat tables denormalize EAV data into a single table per entity, optimized for reads:

-- EAV requires multiple JOINs
SELECT p.entity_id, v.value AS name, d.value AS price
FROM catalog_product_entity p
JOIN catalog_product_entity_varchar v ON v.entity_id = p.entity_id AND v.attribute_id = 71
JOIN catalog_product_entity_decimal d ON d.entity_id = p.entity_id AND d.attribute_id = 75;

-- Flat table: single table, no JOINs
SELECT entity_id, name, price
FROM catalog_product_flat_1
WHERE entity_id = 1;

Product Flat Table Structure

-- Auto-generated flat table per store view
CREATE TABLE catalog_product_flat_1 (
    entity_id INT UNSIGNED NOT NULL,
    name VARCHAR(255) DEFAULT NULL,
    sku VARCHAR(255) DEFAULT NULL,
    price DECIMAL(12,4) DEFAULT NULL,
    status SMALLINT DEFAULT NULL,
    visibility SMALLINT DEFAULT NULL,
    type_id VARCHAR(32) DEFAULT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (entity_id),
    INDEX IDX_NAME (name),
    INDEX IDX_SKU (sku),
    INDEX IDX_PRICE (price),
    INDEX IDX_STATUS (status)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

The flat table contains all searchable/listable attributes in columns, making reads extremely fast.

Flat Table Configuration

Enable Flat Tables

<!-- app/code/Vendor/Module/etc/config.xml -->
<config>
    <default>
        <catalog>
            <flat>
                <enabled>1</enabled>
                <category_enabled>1</category_enabled>
            </flat>
        </catalog>
    </default>
</config>

Or via Admin: Stores > Configuration > Catalog > Catalog > Use Flat Catalog Product

Reindex Flat Tables

# Reindex product flat data
bin/magento indexer:reindex catalog_product_flat

# Reindex category flat data  
bin/magento indexer:reindex catalog_category_flat

# Check index status
bin/magento indexer:status

When Flat Tables Are Updated

Product saved → Flat table updated
Attribute added → Flat table restructured
Category moved → Flat table reindexed
Full reindex → All flat tables rebuilt
// Programmatic flat table rebuild
$flatResource = $objectManager->get(
    \Magento\Catalog\Model\ResourceModel\Product\Flat\Indexer::class
);
$flatResource->rebuild($storeId);

Flat Table Limitations

  • Only stores attributes in the default attribute set
  • Custom attributes must be added to the flat table
  • Maximum columns: MySQL has a practical limit of ~4000 columns
  • Not suitable for highly custom catalogs with hundreds of attributes

Category Flat Table

Category Flat Structure

CREATE TABLE catalog_category_flat_1 (
    entity_id INT UNSIGNED NOT NULL,
    parent_id INT UNSIGNED DEFAULT 0,
    name VARCHAR(255) DEFAULT NULL,
    is_active SMALLINT DEFAULT NULL,
    position INT DEFAULT NULL,
    level INT DEFAULT NULL,
    children_count INT DEFAULT NULL,
    url_key VARCHAR(255) DEFAULT NULL,
    url_path VARCHAR(255) DEFAULT NULL,
    image VARCHAR(255) DEFAULT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (entity_id),
    INDEX IDX_PARENT_ID (parent_id),
    INDEX IDX_IS_ACTIVE (is_active),
    INDEX IDX_URL_KEY (url_key)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Category Tree with Flat Table

-- Fast category tree loading
SELECT entity_id, parent_id, name, level, children_count
FROM catalog_category_flat_1
WHERE is_active = 1
ORDER BY position;

+-----------+-----------+---------------+-------+---------------+
| entity_id | parent_id | name          | level | children_count |
+-----------+-----------+---------------+-------+---------------+
|         2 |         1 | Default       |     1 |              5 |
|         3 |         2 | Electronics   |     2 |              3 |
|         4 |         2 | Clothing      |     2 |              2 |
|         5 |         3 | Phones        |     3 |              0 |
|         6 |         3 | Laptops       |     3 |              0 |
+-----------+-----------+---------------+-------+---------------+

Performance Comparison

// EAV query: ~50ms
$categories = $categoryCollection
    ->addAttributeToSelect(['name', 'url_key', 'image'])
    ->addFieldToFilter('is_active', 1)
    ->load();

// Flat table query: ~5ms
$categories = $flatCollection
    ->addFieldToFilter('is_active', 1)
    ->load();

// 10x performance improvement for read-heavy operations

Flat Table Best Practices

When to Use Flat Tables

USE flat tables when:
  ✓ Product catalog is read-heavy
  ✓ Few custom attributes (< 200)
  ✓ Single-store or few store views
  ✓ Listing/search performance is critical

AVOID flat tables when:
  ✗ Highly custom catalog with 200+ attributes
  ✗ Multi-store with different attribute sets per store
  ✗ Frequent attribute additions/removals
  ✗ Heavy write operations

Optimizing Flat Tables

-- Add custom attribute to flat table
ALTER TABLE catalog_product_flat_1
    ADD COLUMN eco_friendly SMALLINT DEFAULT NULL,
    ADD INDEX IDX_ECO_FRIENDLY (eco_friendly);

-- Remove unused columns to reduce table size
ALTER TABLE catalog_product_flat_1
    DROP COLUMN old_attribute;

-- Check flat table size
SELECT 
    table_name,
    ROUND(data_length/1024/1024, 2) AS data_mb,
    ROUND(index_length/1024/1024, 2) AS index_mb,
    table_rows
FROM information_schema.tables
WHERE table_name LIKE 'catalog_product_flat_%';

Monitoring Flat Table Health

# Check if flat tables are up to date
bin/magento indexer:status catalog_product_flat

# Force rebuild if corrupted
bin/magento indexer:reindex catalog_product_flat --force

# Check for missing attributes in flat table
bin/magento catalog-flat:check

# Enable logging for flat table operations
bin/magento deploy:mode:set developer

Common Issues

Issue Cause Solution
Missing attributes Not in default attribute set Add to flat table manually
Stale data Index not refreshed Run reindex
Large table size Too many columns Remove unused attributes
Slow rebuilds Large catalog Use batch processing

Quiz

1. What is the main advantage of flat tables over EAV?

Question 1 options

2. How many flat tables does Magento create for products?

Question 2 options

3. When should you avoid using flat tables?

Question 3 options

Flashcards

Question

What is a flat table?

Answer

A denormalized table that stores all EAV attributes as columns for fast reads

Question

How many flat tables per store view?

Answer

One flat table per store view for products and categories

Question

What triggers flat table rebuild?

Answer

Product save, attribute addition, category move, or manual reindex

Question

What is the flat table column limit?

Answer

~4000 columns practical limit in MySQL

Question

When are flat tables most beneficial?

Answer

Read-heavy catalogs with fewer than 200 custom attributes

Revision Notes

Key Takeaways

  • 1. Flat tables denormalize EAV data into single tables for fast reads
  • 2. One flat table per store view for products and categories
  • 3. Flat tables are rebuilt on product save and reindex
  • 4. Best for read-heavy catalogs with moderate attribute counts
  • 5. Not suitable for highly custom catalogs with 200+ attributes

Interview Tips

  • Explain the trade-off between flat and EAV tables
  • Discuss when flat tables help vs hurt performance
  • Describe the reindexing process and its impact

Cheat Sheet

Flat Tables:
  catalog_product_flat_{store_id}
  catalog_category_flat_{store_id}

Reindex:
  bin/magento indexer:reindex catalog_product_flat
  bin/magento indexer:reindex catalog_category_flat

Config:
  catalog/flat/enabled = 1
  catalog/flat/category_enabled = 1

Performance:
  EAV query: ~50ms
  Flat query: ~5ms