I had to import a SQL-file with a size of over 20Gb into a mysql-database but ran into a lot of problems doing this.
I don’t have the best server in the world so this import takes about 8 hours to complete and I noticed that after a few hours the import stopped or my connection broke down so I had to start the import again. I’ve tried it for 5 times without succes and got a little frustrated so I decided to write a little and simple PHP-script to split this large file into smaller pieces so I could import these pieces and eventually easily resume the script after the connection broke down.
Splitting the sql-file
I just read every line in with PHP and when I encounter a comment (– ), I create a new file.
//Set time limit to one hour
set_time_limit(3600);
$dir = '/path/to/store/splits';
$file = '/path/to/large/sql/file.sql';
$i = 1000000;
//open large sql-file
$handle = fopen($file,"r");
if($handle) {
while(($buffer = fgets($handle)) !== false) {
//read line and append it to the file with name $i.sql
$newfile = fopen($dir . '/' .$i . '.sql', 'a+');
fwrite($newfile,$buffer);
//if a comment is found, create a new file
if(substr($buffer,0,3) === '-- '){
$i++;
}
}
fclose($handle);
}
Splitting this 20Gb file took about 10 minutes on my server and created approximately 500 files. The largest file was 5Gb and I know I could import a 5Gb-file without a problem.
Importing the sql-file
Importing the file was pretty simple. I wrote a script that loops over all the files and imports them into the database.
set_time_limit(3600000);
//The directory containing the splitted files
$dir = '/path/to/store/splits';
$files = scandir($dir);
ob_start();
//loop over the files and import them into the database
foreach($files as $file){
echo $dir . $file . "\n";
system("mysql -u mysql_username -pmysql_password mysql_databasename < $dir/$file");
ob_flush();
}
In my case, it took more than 8 hours to completely import those database but with the help of these 2 scripts, it worked like a charm.


Nice but didn’t work as is, ‘– ‘ in the data made for a lot of messy files.
I changed ‘– ‘ to ‘\’);’ and each insert became a new file. my SQL file was over a gig and made hundreds of insert files. That took a while but worked great!
Thanks for the code!
Excellent work. Simply awesome. This worked for my 30MB file on a very stupid hosting
Thank you
Your comments script is such a crap.
lets try again:
public static function importFile($file, $separator = ‘– ‘, $func = false) {
if (!$file || !is_file($file) || !$func) return false;
set_time_limit(3600);
$dir = FTP_DIR_ROOT.’upload/temp/splits/’;
self::rmdir($dir,false);
if (!is_dir($dir)) mkdir($dir,0777);
$i = 1000000;
$handle = fopen($file,’r');
if($handle) {
if (is_array($separator)) {
$c = 0;
$separator_length = strlen($separator[0]);
while(($buffer = fgets($handle))!==false) {
$newfile = fopen($dir.’/’.$i.’.sql’,'a+’);
fwrite($newfile,$buffer);
if(substr($buffer,0,$separator_length)===$separator) {
if ($c==$separator[1]) {
$i++;
$c = 0;
fclose($newfile);
}
$c++;
}
}
fclose($handle);
} else {
$separator_length = strlen($separator);
while(($buffer = fgets($handle))!==false) {
$newfile = fopen($dir.’/’.$i.’.sql’,'a+’);
fwrite($newfile,$buffer);
if(substr($buffer,0,$separator_length)===$separator) {
$i++;
fclose($newfile);
}
}
fclose($handle);
}
}
set_time_limit(3600000);
$files = scandir($dir);
ob_start();
foreach($files as $j => $file) {
if ($func==’db’) {
echo $dir.$file.’\n’;
system(‘mysql -u ‘.DB_USERNAME.’ -p’.DB_PASSWORD.’ ‘.DB_NAME.’ < '.$dir.'/'.$file);
ob_flush();
} else {
call_user_func_array($func, $dir.'/'.$file);
}
}
return $i;
}
Thanx for your solution. Here I made in 15 minutes a better solution:
$file) {
if ($func==’db’) {
echo $dir.$file.’\n’;
system(‘mysql -u ‘.DB_USERNAME.’ -p’.DB_PASSWORD.’ ‘.DB_NAME.’
have fun
visit ajaxel.com – the greatest cms!
thank you! this helps me
Wow !o!
It is very good solution. I have same problem and try many times but failed. Now I can migrate a huge database to other server with this script.
Thanks,
JT