1

n個のcsvファイルがあり、それらを相互に比較して後で変更する必要があります。問題は、各csvファイルに約800.000行あることです。

csvファイルを読むために私はfgetcsvを使用します、そしてそれはうまくいきます。いくつかのメモリパイクを取得しますが、最終的には十分に高速です。しかし、アレイを相互に比較しようとすると、時間がかかります。

もう1つの問題は、ファイルの数がnであるため、fgetcsvでcsvデータを取得するためにforeachを使用する必要があることです。最終的に1つの超大型配列になり、array_diffと比較できません。だから私はそれをネストされたforeachループと比較する必要があり、それは時間がかかります。

理解を深めるためのコードスニペット:

foreach( $files as $value ) {
    $data[] = $csv->read( $value['path'] );
}

私のcsvクラスはfgetcsvを使用して、出力を配列に追加します。

fgetcsv( $this->_fh, $this->_lengthToRead, $this->_delimiter, $this->_enclosure )

すべてのcsvファイルのすべてのデータは$data配列に保存されます。これはおそらく、1つの配列のみを使用する最初の大きな間違いですが、foreachを使用せずにファイルを柔軟に維持する方法がわかりません。私は柔軟な変数名を使おうとしましたが、私もそこに固執しました:)

今、私はこの大きな配列を持っています。通常、値を相互に比較し、ファイル1のデータがファイル2に存在するかどうかを確認する場合は、array_diffまたはarray_intersectを使用します。しかし、この場合、私はこの1つの大きな配列しか持っていません。そして、私が言ったように、foreachを実行するには何年もかかります。

また、たった3つのファイルの後で、3*800.000エントリの配列があります。私は10ファイル後に私の記憶が爆発するだろうと思います。

では、PHPを使用してn個の非常に大きなcsvファイルを比較するためのより良い方法はありますか?

4

1 に答える 1

5

SQLを使用する

  • CSVファイルと同じ列のテーブルを作成します。
  • 最初のCSVファイルからデータを挿入します。
  • インデックスを追加してクエリを高速化します。
  • 行を読み取り、SELECTを発行して、他のCSVファイルと比較します。

n個のファイルを比較する方法については説明していません。そのためには、いくつかの方法があります。A1にはあるが、A2にはない行を検索したいだけの場合は、テーブルにブール列の差分を追加する必要があります。行が繰り返されるファイルを知りたい場合は、テキスト列、または行が複数のファイルに含まれる可能性がある場合は新しいテーブルが必要になります。

編集: MySQLを使用している場合のパフォーマンスに関する簡単な説明(他のRDBMSについてはあまり詳しくありません)。

行を1つずつ挿入するのは遅すぎます。LOAD DATACSVファイルをDBサーバーのファイルシステムに直接配置できない限り、おそらく使用することはできません。したがって、最善の解決策は、CSVの数百行を読み取ってから、複数の挿入クエリを送信することだと思いますINSERT INTO mytable VALUES (..1..), (..2..)

他のファイルで読み取った行ごとにを発行することはできないSELECTため、別のテーブルに配置することをお勧めします。次に、複数テーブルの更新を発行して、テーブルt1とt2で同一の行をマークします。UPDATE t1 JOIN t2 ON (t1.a = t2.a AND t1.b = t2.b) SET t1.diff=1

多分あなたはsqliteを使ってみることができます。ここでは同時実行の問題はなく、MySQLのクライアント/サーバーモデルよりも高速である可能性があります。また、sqliteを使用するために多くの設定を行う必要はありません。

于 2011-10-02T11:47:02.150 に答える