- ベストアンサー
CSVファイルによる検索の高速化
CSVファイル内を検索し、一致した行を抽出して出力する際、みなさんはどのような方法を選びますか?私の手元にあるCSVファイルは3000行以上のファイルで、500KBあります。出来る限り、高速化したいのです。文字コードはUTF-8で日本語が主に書かれています。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
CSVなどのファイルを開く場合は、基本的に fopen関数 file関数 file_get_contents関数 ぐらいになると思いますが、 file関数はすべての行を配列に落とすため、メモリが一気に使用されます。 file_get_contentsもすべてのデータを取得して何らかの変数に代入するので、 配列ほどではないにしても一度にメモリを消費すると思います。 また、一度に巨大なデータを一気に取得して何らかの展開を行う方法では高速化はされませんので、 fopen関数を使い、whileなどでループさせながら、fgets(fread)関数で一行ずつ読み込みを行う、という方法になると思います。 そうしますと次に考えるのは、検索で一致した行を探すという内容ですが、 これは要件次第ですのでなんとも言えませんが、 fgetsしてきた一行から文字列を検索する方法で一番早いと思われるのは、strpos関数ですが、マルチバイトに対応していない為、今回は使えません。 mb_strpos関数もありますが、mbの類は結構遅いです。 なので、preg_matchを使用するのが一番早いと思います。 そして、preg_matchで適合したもののみ、配列などに代入していくと。 長々とここまで書きましたが、それでも速度に問題があるなら、データベースにデータを移して、SQLで検索をかけた方が良いと思います。
その他の回答 (3)
- oraora777
- ベストアンサー率20% (56/268)
fopen()でファイルオープンしてでfgets()で取得して利用時にCSVをexplode()やstr_getcsv()で分割するなら fgets()の代わりにfgetcsv()を使って取得時に配列に分離してしまった方が良いと思いますよ。
お礼
ご回答ありがとうございます。 fgetcsv()という便利な関数があるんですね。ありがとうございます。
- yambejp
- ベストアンサー率51% (3827/7415)
どうしても高速化が必要なときはコマンドラインのgrepなどを 利用してしまうことがおおいですね
お礼
ご回答ありがとうございます。 なるほど!!コマンドラインで検索するんですね。早い結果が期待できそうです。ありがとうございました。
- inu2
- ベストアンサー率33% (1229/3720)
CSVファイルをパースしたあとにDBに突っ込んで検索させる。 CSVファイルを更新した場合には自動的にDBに保存しなおしさせるように仕込んでおく 次からはDBを読みに行けばいいだけ。 CSVが頻繁に更新されるのであれば、memcacheなどを使ってメモリに展開させておくかな。 いずれにせよ、ファイルを直接ずるずる引きずりまわすのはメモリも食うし何しても結果的に満足いく速度は出ない。
お礼
ご回答ありがとうございます。 なるほど、元のCSVファイルを更新するたびにDBに突っ込んでおくんですね。となると、検索はPHPでやるのでなく、DBに任せておくのが無難ですか。ありがとうございました。
お礼
詳しい回答ありがとうございます。 やはりfopen関数になりますか。file関数はメモリを食う原因なので、私も使用はないかなぁ〜と思っています。内容に合致した1行を抽出するには、やはりfopen関数がもってこいですね。 私が気になっていたのはこのマルチバイトの扱いですが、ここはpreg_matchですか。とても参考になりました。