クエリが10個あり、各クエリが特定のテーブル(つまり10個の異なるテーブル)を更新している場合。MySQLは接続ごとに同時クエリをサポートできますか?
1つのmySQL接続を開き、10スレッドを生成できます。各スレッドは1つずつ実行する代わりに同時に実行できるように1つのクエリを処理します。
ありがとうございます!
クエリが10個あり、各クエリが特定のテーブル(つまり10個の異なるテーブル)を更新している場合。MySQLは接続ごとに同時クエリをサポートできますか?
1つのmySQL接続を開き、10スレッドを生成できます。各スレッドは1つずつ実行する代わりに同時に実行できるように1つのクエリを処理します。
ありがとうございます!
ありませんあなたがすることはできません:
MySQLクライアントライブラリ(少なくともネイティブC 1)は、異なるスレッドから同じ接続を使用するようにスレッドセーフではありません。スレッドごとに接続を使用する必要があります。
MySQLプロトコルの仕組みのため、1つの接続しか開いていない場合、これらは1つずつサーバーに送信されます。
更新(INSERT DELAYEDおよびUPDATE LOW_PRIORITYクエリ)を使用すると、並列(MySQL APIの観点では非同期)で実行される更新/挿入クエリが必要です。
作成なしファイル「log.conn.txt」はありませんので、単一mysqlクライアント接続への同時クエリの間に矛盾はありません。
<?
declare(ticks=1);
pcntl_signal(SIGUSR1, create_function('$signo', 'sleep(1);while (($pid=pcntl_wait(@$status, WNOHANG))>0) {}'));//protect against zombie children
$pdo=new PDO('mysql:host=192.168.0.2;port=3306;dbname=baseinfo', 'dev', 'dev',
array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND=>'set names utf8'
)
);
for ($i=0; $i<20; ++$i)
{if (($pid=pcntl_fork())===-1)
{//...
continue;
}
else if ($pid)
{$pids[]=$pid;
pcntl_wait($status, WNOHANG); //protect against zombie children, one wait vs one child
}
else if ($pid===0)
{ob_start();//prevent output to main process
register_shutdown_function(create_function('$pars', 'ob_end_clean();posix_kill(posix_getppid(), SIGUSR1);posix_kill(getmypid(), SIGKILL);'), array());//to kill self before exit();, or else the resource shared with parent will be closed
for ($j=0; $j<200; ++$j)
{try
{file_put_contents('log.'.$i.'.txt', $pdo->query('select partner_login from base_account where id=100')->fetch(PDO::FETCH_COLUMN, 0)."\t".time().substr(microtime(),2,6)."\n", FILE_APPEND);
}
catch (Exception $e)
{if ($pdo->getAttribute(PDO::ATTR_SERVER_INFO)==='MySQL server has gone away')
{file_put_contents('log.conn.txt', time().substr(microtime(),2,6).":{$i}:{$j} lost\n", FILE_APPEND);
$pdo=&new PDO('mysql:host=192.168.0.2;port=3306;dbname=baseinfo', 'dev', 'dev',
array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND=>'set names utf8'
)
);
}
}
usleep(50000);
}
exit();//avoid foreach loop in child process
}
}
//wait all child to end, avoid close db connection before all children self killed
foreach ($pids as $p)
{pcntl_waitpid($p, $status);
}
?>
mysqlのlibクライアントとの通信でブロックされた子プロセスが2つまたは3つで、これらの子プロセスが終了しない場合があります。 "PDO :: ATTR_TIMEOUT"は問題を解決しません – diyism
何が同じスレッドから複数の非同期のクエリを開始する場合は? –