insert… select…を実行中にcount(*)を実行することは可能ですか? mysql / phpのクエリ?

StackOverflow https://stackoverflow.com/questions/331619

  •  22-07-2019
  •  | 
  •  

質問

別のPHPスクリプトがinsert ... select ...クエリを実行している間に、PHPスクリプトで単純なcount(*)クエリを実行することは可能ですか?

状況は、別のテーブルから〜1M以上の行を持つテーブルを作成する必要があり、挿入中にページがフリーズしているとユーザーに感じさせたくないため、カウントを更新し続けようとしていますが、挿入のバックグラウンドで select count(\ *)from table を使用すると、挿入が完了するまで0しか取得できませんでした。

では、MySQLが最初に部分的な結果を返すようにする方法はありますか?または、insert ... select ...クエリとほぼ同じパフォーマンスを持ちながら、前のselectクエリからフェッチされたデータを使用して一連の挿入を高速に行う方法はありますか?

環境はphp4.3およびMySQL4.1です。

役に立ちましたか?

解決

単一のINSERT ... SELECTを実行している場合、いいえ、中間結果を取得することはできません。実際、ユーザーはステートメントまたはトランザクションの部分的な結果のみを示す中間状態のデータベースを見るべきではないため、これは悪いことです。詳細については、 ACID コンプライアンスをご覧ください。

とはいえ、MyISAMエンジンはこれで高速に動作する可能性があります。途中で打ち切ったときに、MyISAMがINSERT ... SELECTからのすべての行ではなく、いくつかの行をコミットしたのを見たことはかなりあります。ただし、テーブルがどのエンジンを使用しているのかはまだ説明していません。

他のヒント

パフォーマンスを低下させることなく?ありそうにない。パフォーマンスが少し低下しますが、多分...

しかし、なぜ定期的にテーブルを作成し、数百万行を挿入するのですか?これを行うことはめったにありませんが、これには長い時間がかかることを管理者に警告することはできません(おそらく、そのようなことを行うことを許可されている唯一の管理者)。これを常に実行している場合、それを間違っている実行していないことを本当に確信していますか?

PHPリクエスト中に一度に100万行をコピーする場合、これは赤い旗であるというSteinのコメントに同意します。

私は、人々がSQLを微最適化しようとする大多数の場合、別の方法で問題にアプローチすることで、はるかに高いパフォーマンスとスループットを得ることができると信じています。 SQLがボトルネックになることはありません。

他のユーザーは、コミットされるまで挿入を見ることができません。通常、これは良いことです。それは、彼らが半完了データを見ることができないようにするからです。ただし、中間データを表示したい場合は、「commit」を呼び出すことができます。挿入中。

ところで、自動コミットをオンにするようにだれにも言わないでください。膨大な時間の浪費。 「削除して再挿入」があります自動コミットをオフにすると、1/3の時間がかかるデータベースでのジョブ。

明確にするために、MySQL 4はデフォルトでトランザクションを使用するように設定されていません。正しく覚えていれば、挿入ごとにテーブル全体をロックするMyISAMテーブルタイプを使用します。

最善の策は、などのMySQL一括挿入関数のいずれかを使用することです。大量のデータを挿入する際に劇的に高速であるため、LOAD DATA INFILE 。カウントについては、挿入を1000(またはY)のNグループに分割し、進行状況メーターをNセクションに分割して、各グループの要求に応じて更新することができます。

編集:もう1つ考慮すべき点は、これがテンプレートの静的データである場合、「select into」を使用できることです。同じデータで新しいテーブルを作成します。アプリケーションが何であるか、または意図した機能がわからないが、それでも同様に機能する可能性があります。

コンソールにアクセスできる場合、さまざまなステータスの質問をして、探している情報を確認できます。 " SHOW processlist"のようなコマンドがあります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top