0

PDO を使用してループに多くの行を挿入する必要がある状況を想像してみましょう。

$sql = "INSERT INTO products (name, price) VALUES (:name, :price)";
$stmt = $db->prepare($sql);

for ($i = 0; $i < 100; $i++)
{
    $name = md5(rand(0, 1000));
    $price = rand(0, 1000);

    $stmt->bindParam(':name', $name);
    $stmt->bindParam(':price', $price);

    try
    {
        $result = $stmt->execute();

        if (!$result)
        {

            print_r($db->errorInfo());
        }

        echo $db->lastInsertId();
    }
    catch (Exception $e)
    {
        echo $e->getMessage();
    }
}

この方法では、100 行すべてがデータベースに挿入されるわけではありません。23 行目の echo は次のような出力を出力します:

1 2 3 4 5 ... 59 60 61 61 61 61 61 61

20行目のprint_rが出力されます

 Array (
     [0] => 00000
     [1] => 
     [2] =>  
 )

PDO エラー コード 00000 は、すべて正常に動作していることを意味します。また、行は影響を受けませんでした。$result が false である行を手動で挿入しようとすると、すべて問題ありません。

61 行のみがテーブルに挿入されます。そして、スクリプトが実行されるたびにこの数値が変化し、これは本当に奇妙です。

なんで?

他の方法では、すべての挿入クエリから 1 つのクエリを作成でき、100 行すべてが挿入されます。これは、コード付きのペーストビンへのリンクです。

テーブル構造は次のとおりです。

CREATE TABLE IF NOT EXISTS `products` (
`id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `price` int(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

ところで。percona MySQL サーバー (5.5) と HandlerSocker プラグインを使用しています。そして、HandlerSocket を使用して行を挿入しようとしました。ここにコードがあります

$hs = new \HSPHP\WriteSocket();
$hs->connect();

$id = $hs->getIndexId('test','products','','name,price');
$loops_number = 10000;

for ($i = 0; $i < $loops_number; $i++)
{
    $name = 'handler-'.md5(rand(0, 1000));
    $price = rand(0, 1000);

    $hs->insert($id, array($name, $price));
}

そして、私はこの後、DBに〜14000行あります。なんで?また、ループ数を変更した場合 (変数$loops_number ) -

if 10 loops - I have 100 rows in DB table
if 50 loops - 50 rows
if 100 loops - 100 rows
if 500 loops - 500 rows
if 1000 loops - ~1100 rows and this number always change. (if I truncate table and run script again)

私のMySQLサーバーに問題があるようですか?

4

2 に答える 2

0

この問題は、PHP を再インストールすることで解決します。(私はこのレポからPHPを使用しました ppa:ondrej/php5:)

HandlerSocket の挿入に関する問題: 1. ループ内にインデックスを作成する 2. HandlerSocket による挿入クエリを作成する場合は、id (自動インクリメント) を手動で設定する方がよい

于 2013-08-01T17:58:28.460 に答える