1

いくつかの複雑なデータをmysqlデータベースに挿入しようとしましたが、実装のパフォーマンスに問題があります。私のデータは次のようになります:

user1
  question1_1
    answer1_1_1
    answer1_1_2
    answer1_1_3
    ...
  question1_2
    answer1_2_1
    answer1_2_2
    ...
  ...
 user 2
 ...

このために、データベースに3つのテーブルを定義しました

users columns[userid, name,...]
questions columns[questionid, userid, questiontext]
answers columns[answerid, questionid, answertext]

データベースに挿入したい大量のデータを受け取ります。テーブルがリンクされているので、ユーザーを挿入し、IDを取得して、質問のVALUESでこれを使用する実装ができました...動作しますが、個別の数が多いため、「最大実行時間が30秒を超えました」と表示されます。 mysql挿入ステートメント。

私の現在のコードは次のようになります:

for ($i=0; $i<sizeof($users); $i++)
{
  $user = $users[$i];
  $sqlstr = "INSERT INTO users (username) VALUES ('".$users[$i]->id."')";

  mysql_query($sqlstr);
  $userid = mysql_insert_id(); 

  for ($j=0; $j<sizeof($user->question); $j++)
  {
    $question = $user->question[$j];

    $sqlstr = "INSERT INTO question (userid,creator,date) VALUES (".$userid.",'".$question->creator."','".$question->date."')";

    mysql_query($sqlstr);
    $questionid = mysql_insert_id(); 

    $rows = array();
    $sqlstr = "INSERT INTO answers (questionid,name,value) VALUES ";
    for ($k=0; $k<sizeof($question->answers); $k++)
    {
      $rows[] = "('".$questionid."','".$question->answers[$k]->name."','".$question->answers[$k]->value."')";
    }
    $sqlstr = $sqlstr.implode(',',$rows);
    mysql_query($sqlstr);
  }
}    

前の挿入のIDが次の挿入ステートメントで使用されている場合、個別の挿入ステートメントを1つの大きなステートメントに組み合わせるにはどうすればよいですか?LAST_INSERT_ID()を試しましたが、これは期待どおりに機能しません。そのテーブルの最後のIDを参照しているようです。

それとも別の解決策がありますか?

4

1 に答える 1

1

SQLステートメントをトランザクションでラップできます。dev.mysql.com/docを参照してください。 これにより、データベースの入力が高速化されると同時に、小さな単一の挿入ステートメントを発行し続けることができます。

トランザクションを開始すると、コミットするまですべてのディスクアクセスが一時停止されます。これは、すべての挿入が一度にディスクに書き込まれることを意味します。また、すべてのハウスキーピングの更新は、一度だけ書き込む必要があります。

例えば

mysql_query('START TRANSACTION');
<your code>
mysql_query('COMMIT');

:(を使用してROLLBACK)トランザクションを中止すると、驚くほど遅くなる可能性があります。

于 2012-04-13T06:47:54.500 に答える