LW IT Solutions
« Blog Overview /IT & Networks / Extracting Specific Tables from Massive SQL Dumps...
This post in other languages:

Extracting Specific Tables from Massive SQL Dumps using PHP

Extracting Specific Tables from Massive SQL Dumps using PHP

Sometimes only one database or a specific set of tables needs to be restored from a multi-gigabyte (e.g., 5GB) MySQL dump. Opening a file of that size in standard text editors like VS Code or Notepad++ usually leads to extreme lag or a complete system crash.

Instead of struggling with desktop software or complex command-line tools like awk or sed, we can use a simple, memory-efficient PHP script to extract exactly what we need.

Seven lines from a mysqldump file with the state of the extraction switch after each one, alongside a comparison of the memory used by file_get_contents and fgets
The database marker sets the switch, the table marker corrects it — everything in between is copied unchanged.

The Solution: Stream Processing

The trick to handling massive files in PHP is to avoid loading the entire file into memory at once (which functions like file_get_contents() do). By using PHP’s fgets() function, we can stream and process the file line by line.

The script below looks for the standard mysqldump comments that indicate the start of our target database or table (e.g., -- Current Database: db). When it finds our target, it toggles a flag to start writing those lines to a new file. As soon as it encounters the start of a different database or table, it turns the flag off.

Here is the complete script:

<?php
ini_set('memory_limit', '2G');

$inputFile = 'dump_5GB.sql';
$outputFile = 'db_fragment.sql';
$targetName = 'db';

$in = fopen($inputFile, 'r');
$out = fopen($outputFile, 'w');

$isExtracting = false;

while (($line = fgets($in)) !== false) {
    if (strpos($line, '-- Current Database: `' . $targetName . '`') === 0 || 
        strpos($line, 'USE `' . $targetName . '`;') === 0) {
        $isExtracting = true;
    } elseif (strpos($line, '-- Current Database: `') === 0 || 
              strpos($line, 'USE `') === 0) {
        $isExtracting = false;
    }

    if (!$isExtracting) {
        if (strpos($line, '-- Table structure for table `' . $targetName . '`') === 0 ||
            strpos($line, '-- Table structure for table `' . $targetName . '_') === 0) {
            $isExtracting = true;
        } elseif (strpos($line, '-- Table structure for table `') === 0) {
            $isExtracting = false;
        }
    }

    if ($isExtracting) {
        fwrite($out, $line);
    }
}

fclose($in);
fclose($out);

This method keeps memory usage practically flat—well under a few megabytes—and processes gigabytes of SQL data in just a few seconds.

Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in Touch

Briefly describe your project or inquiry for a tailored response. This site is protected by reCAPTCHA.

2 comments

  1. Malin Osterholm

    Streaming with fgets() instead of loading the file is the obvious answer once seen, and the memory figures make the case better than any argument about elegance.

    One question about robustness: the script keys on mysqldump’s comment lines. What happens with a dump produced using --skip-comments which is what our hosting provider ships?

    1. Lukas Wojcik Author

      Then the markers are gone and the script writes an empty file — no error, no warning, just a result of zero bytes that looks like a missing table rather than a missing anchor.

      Two anchors survive most flag combinations. The USE `db`; statements, which the script already looks for, are emitted for multi-database dumps regardless of comment settings. And the DROP TABLE IF EXISTS / CREATE TABLE lines are structural rather than decorative, so they are present in essentially every dump — keying the table-level extraction on those makes it independent of the comment style.

      The general habit worth adopting: read the first fifty lines of the dump before running anything against it. That answers which anchors exist, whether the file is one database or many, and whether it was written with extended inserts — three questions that decide whether the script works at all, and all three visible in about ten seconds.

Write a comment

The email address is not published. Required fields are marked with an asterisk.

ALL ARTICLES & CATEGORIES

CCTV

Follow this category by RSS

Cloud & AI

Follow this category by RSS

Data Privacy

All 12 articles in this category Follow this category by RSS

Digital Analytics

All 45 articles in this category Follow this category by RSS

Digital Marketing

All 25 articles in this category Follow this category by RSS

IT & Networks

All 15 articles in this category Follow this category by RSS

Raspberry PI

Follow this category by RSS

Smart Home

All 13 articles in this category Follow this category by RSS

Web Development

Follow this category by RSS

WordPress Plugins & Tricks

Follow this category by RSS