从大的sql备份中找出单张表:

        从mysqldump命令导出的大的sql文件中快速找出单张表,php协程方式读取大文件。

<?php
set_time_limit(0);
// ini_set('max_execution_time', 0);
ob_end_clean();
$memory = memory_get_usage();	// 内存使用初始大小
$byte_to_mb = 1024;		// 用于单位换算


// 开始查找的行数
$line = 1;
// $line = 400000;

// sql文件名
$filename = 'dmdb-20180601';

if(!is_dir($filename))
{
	mkdir($filename);
}

function get_sql($filename)
{
	$file = fopen($filename.'.sql', "r");
	while(!feof($file))
	{
		yield fgets($file, 40240);
	}
	fclose($file);
}

$result = get_sql($filename);
$table_name = 'first';
$i = 1;

echo "<pre>";
foreach ($result as $key => $value)
{
	if($i < $line){
		$i++;
		continue;
	}
	if(substr($value, 0, 12) == 'CREATE TABLE')
	{
		$first = strpos($value, '`');
		$last = strrpos($value, '`');
		$table_name = substr($value, $first + 1, $last - $first - 1);
		echo round((memory_get_usage() - $memory) / $byte_to_mb, 3).' k ---------- '.$table_name."<br>";
		flush();
	}
	file_put_contents($filename.'/'.$table_name.'.sql', $value, FILE_APPEND);
}
echo ((memory_get_usage() - $memory) / $byte_to_mb).' k';


去除 drop table 语句:

        下面的和上面一样,只不过是用来去除drop table语句的:

<?php
set_time_limit(0);
ini_set('max_execution_time', 0);
ob_end_clean();
$memory = memory_get_usage();	// 内存使用初始大小
$byte_to_mb = 1024;		// 用于单位换算


// 开始查找的行数
$line = 1;
// $line = 400000;

// sql文件名
$filename = 't_bond_notification_msg';



$dirname = $filename.'-drop';
if(!is_dir($dirname))
{
	mkdir($dirname);
}

function get_sql($filename)
{
	$file = fopen($filename.'.sql', "r");
	while(!feof($file))
	{
		yield fgets($file, 40240);
	}
	fclose($file);
}

$result = get_sql($filename);
$table_name = 'first';
$i = 1;

echo "<pre>";
foreach ($result as $key => $value)
{
	if($i < $line){
		$i++;
		continue;
	}
	if(substr($value, 0, 10) == 'DROP TABLE')
	{
		$first = strpos($value, '`');
		$last = strrpos($value, '`');
		$table_name = substr($value, $first + 1, $last - $first - 1);
		echo round((memory_get_usage() - $memory) / $byte_to_mb, 3).' k ---------- '.$table_name."<br>";
		flush();
	}
	file_put_contents($dirname.'/'.$table_name.'.sql', $value, FILE_APPEND);
}
echo ((memory_get_usage() - $memory) / $byte_to_mb).' k';

方法二:

        先找出表所在的行,然后将表写入文件,不过会继续写下面的表,需要手动暂停。

<?php
set_time_limit(0);
// ini_set('max_execution_time', 0);
ob_end_clean();
$memory = memory_get_usage();	// 内存使用初始大小
$byte_to_mb = 1024;		// 用于单位换算
$time = time();
echo "<pre>";

// 开始查找的行数
$line = 0;
// $line = 417090;

// sql文件名
$filename = 'dmdb-20180601';

$dirname = $filename.'-line';
if(!is_dir($dirname))
{
	mkdir($dirname);
}

function get_sql($filename)
{
	$file = fopen($filename.'.sql', "r");
	while(!feof($file))
	{
		yield fgets($file);
	}
	fclose($file);
}

$result = get_sql($filename);
$table_name = 'first';
$str = "CREATE TABLE `t_bond_notification_msg` (\n";

$i = 1;
$start_line = 0;
foreach ($result as $key => $value)
{
	if($i < $line){
		$i++;
		continue;
	}
	$i++;
	if($value == $str)	// 这个语句只适合找出所在的行
	{
		$start_line = $i;
		break;
	}
}
echo 'time: '.(time() - $time).' s<br>';
echo 'size: '.((memory_get_usage() - $memory) / $byte_to_mb).' k<br>';
echo 'line: '.$start_line;
echo "<br>";
flush();



$result = get_sql($filename);
$j = 0;
$start_line = $start_line - 10;
foreach ($result as $key => $value)
{
	if($j < $start_line){
		$j++;
		continue;
	}
	$j++;
	if(substr($value, 0, 12) == 'CREATE TABLE')
	{
		$first = strpos($value, '`');
		$last = strrpos($value, '`');
		$table_name = substr($value, $first + 1, $last - $first - 1);
		echo 'memo: '.round((memory_get_usage() - $memory) / $byte_to_mb, 3).' k ---------- '.$table_name."<br>";
		echo 'line: '.$j.'<br>';
		echo 'time: '.(time() - $time).'<br>';
		flush();
	}
	file_put_contents($dirname.'/'.$table_name.'.sql', $value, FILE_APPEND);
}