5

フォーム リクエスト 10'000 + 同様の行から一度に挿入できるようにする必要があります。現在、1行の準備済みステートメントを10'000回ループさせて、各変数を再バインドすることでそれを行いました。

for ($i=0; $i < intval($cloneCount); $i++) 
{
    ... 9 other bindParam
    $insertG->bindParam(':v1', $v1, PDO::PARAM_STR);
    $insertG->bindParam(':v2', $v2, PDO::PARAM_INT);
    $insertG->execute();
}

達成するのに約 30 秒かかり、確かに良い習慣ではありません。今日は10000だけど明日は100000になるかも

1 つのクエリに複数の行を挿入する場合(v1,v2),(v1,v2)...、各値を新しいパラメーターにバインドする必要があるため、1 つのクエリに約 100,000 の bindedParam が必要になると思います。それが UTF-8 で、1 文字あたり約 2 バイト (最大 4 まで可能であることはわかっています) をカウントする場合、クエリは約 10 から 20 MB になり、mysql サーバーは別のマシン上にあります。これを言うと、設計が不十分なリクエストが成功するのに30秒しかかからなかったことに驚いています。

1 行だけを送信し、mysql サーバーに最後の行を 10,000 回複製するように指示する方法はありますか?

部分解の編集

Bill Karwin と Zsolt Szilagy のアドバイスに従います。リモートmysqlサーバーへの10'000挿入の次の調整により、なんとか5〜6秒に短縮できました。

$dataBase->beginTransaction();

$insertG = $dataBase->prepare('INSERT INTO G...)
...
10 * bindParam of all kinds

for ($i=0; $i < 10000; ++$i) 
{ 
    $hashKey = sha1(uniqid().$i); //$hashKey is a binded param
    $insertG->execute();
}
$dataBase->commit();
4

3 に答える 3

1

あなたの質問から正しく理解できれば、1行だけ送信してmysqlサーバーに最後の行を10'000回複製するように指示する方法はありますか? 同じ行を複数回複製する必要があります。

そのために、特に定期的に行っている場合は、集計テーブル (制限と予想される行数が 100000 など) がありCROSS JOIN、ループではなくセットを使用して db 側でそれを行うのに役立つ場合があります。

集計表の作成

CREATE TABLE tally(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY);

DELIMITER $$
CREATE PROCEDURE sp_populate_tally(IN n INT)
BEGIN
    DECLARE i INT DEFAULT 1;
    WHILE i <= n DO
        INSERT INTO tally VALUES (NULL);
        SET i = i + 1;
    END WHILE;
END$$
DELIMITER ;

CALL sp_populate_tally(100000);

行を10000回複製するには

INSERT INTO table_name (n1, n2, ...)
SELECT n1, n2, ... 
  FROM
(
  SELECT 1 n1, 'TextValue1' n2, ...
) a CROSS JOIN tally t
 WHERE t.id <= 10000;

ここにSQLFidlleデモ ( UPDATED ) があります。

于 2013-06-02T23:04:32.687 に答える