人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

while等で9万行目以降まで空回しさせれば、9万行目以降からデータ読み込みさせることは可能ですが、
このような場合9万行まで空回しが発生し、空回ししている時間だけ処理時間が多くかかってしまいます。

どうにか空回しさせずに、CSVファイルを指定行から読み込ませたいのですが、
ご存じの方法などあれば、教えてください。

system関数とかを利用する場合の例なども詳しく教えて頂けますと、助かります。


【現在のコード】※簡素化のため、一部改変・省略済み

$csvfile = fopen('test.csv','r');
$offset = 90000;

while(($data = fgetcsv($csvfile,0,',')) !== FALSE){
$count = $count + 1;
if($count => $offset ){
echo($data[0]);
echo($data[1]);
echo($data[3]);
・・・
}
}

●質問者: sandbox69
●カテゴリ:ウェブ制作
✍キーワード:CSV ECHO test コード データ
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● y-kawaz
●30ポイント

事前処理で、例えば1ファイル1000行で複数ファイルに分割しておくとかでは駄目でしょうか?

9万30行目から読みたければ 91.csv を開いて最初の29行をスキップする、といった感じで。

◎質問者からの返答

10万行のCSVファイルを例えば1000行ないし1万行に分割するのに、

PHP上で制御できましたっけ???

仮に出来るとした場合、その処理の方が重くなったりはしませんか???

そうでないようであれば、ファイル分割のための関数などをご教示いただけないでしょうか?


2 ● ホーエンハイム
●30ポイント

読み込むべきCSVファイルが変化しないものであれば、事前に各行の位置(fseek関数で移動する位置。ファイル先頭からのバイト数)を記録した固定長インデックスファイル(1行につき12桁固定で十分でしょう)を作っておき、それを参照させるといいでしょう。

◎質問者からの返答

>読み込むべきCSVファイルが変化しないものであれば

CSVファイルは変化しません。

念のため確認ですが、インデックスファイルを作成するのに、

事前に10万行はループさせる必要があるということにはなりませんか???

となると、その処理にかかる負荷がどの程度になるのかにもよりますよね?

サンプルソースなどをご提示いただくことは可能でしょうか???


3 ● hanako393
●0ポイント

>このような場合9万行まで空回しが発生し、空回ししている時間だけ処理時間が多くかかってしまいます

本当にどれだけ時間がかかってるか計測済みですか?

感覚論で、処理時間がかかるといってるわけではないでしょか?

実際には大して時間はかかってませんよ。

CSVファイルのまま、何の小細工もしないで9行目から読むことはできません。

ファイルを分割して持つとかインデックスをもつとかするしかありません。

回答1、回答2に否定的で、CSVファイルはそのままの状態でというのなら

9万行空まわししかないです。実際にはそれほど時間はかかってません。

>CSVファイルを指定行から読み込ませたいのですが

CSVファイルで何万行も管理するのは無謀なんです。

DBで管理してDBから読み書きしてください。

DBが使えないのなら、現状のままでいくしかありません。

◎質問者からの返答

> 本当にどれだけ時間がかかってるか計測済みですか?

> 感覚論で、処理時間がかかるといってるわけではないでしょか?

> 実際には大して時間はかかってませんよ。

データの仕様上、カラムが30近く、あるカラムのデータはテキストベースで最大800文字程度。

計測済みの上での質問であり、より高速化させたいというのが願いです。

>CSVファイルのまま、何の小細工もしないで9行目から読むことはできません。

>ファイルを分割して持つとかインデックスをもつとかするしかありません。

そうなんですね、ありがとうございます。

>CSVファイルで何万行も管理するのは無謀なんです。

>DBで管理してDBから読み書きしてください。

CSVを読み込んでDBに登録させるという処理上のことです。

DB登録後は、SQL文のlimit等で制御している処理時間に問題はありません。


4 ● koriki-kozou
●30ポイント ベストアンサー

可変長の場合、空送り処理が必要になるのは、実はどの言語を用いていても同じ

問題は、言語の処理速度

コンパイルしてしまうCやJAVAを用いればより早く処理できる

phpはループを重ねれば重ねるほどメモリを喰らい続けるため、さらに事態は悪化する

CやJAVAが無理であればperl(pythonはcsvの取り扱いに少し癖がある)などを使うことを考えたほうがいいかもしれない

サーバにデータを送る前の段階や送る最中にファイルを分割しておくことも考えたほうがいいかもしれない


具体的にどうすべきかについてはさておき、今回の質問に直で答えるとすれば例えば下記のような具合

(テストデータはExcelで作成したものを利用しているため9万行というようなデータを吐き出せるシステムで作成したcsvファイルでも対応できるかは未確認。特に改行コードについては注意が必要)

<?php
$filename = './test.csv';
$offset = 3;

$path = realpath($filename);// php から見たパスとshellから見たパスは違うため
$offsetByte = shell_exec('head -n ' . ($offset - 1) . ' ' . $path . ' | wc -c');// 読み飛ばすデータサイズ取得

$csvfile = fopen($filename, 'r');
fseek($csvfile, $offsetByte); // 読み飛ばす
while(($data = fgetcsv($csvfile, 8192, ',')) !== FALSE){
 echo($data[0]);
 echo($data[1]);
 echo($data[3]);
}
?>

fgetcsv の第二引数が 0 の場合の処理と数値を指定した場合では内部処理が異なる

1024,2048,4096,8192などの数値(セクタサイズの倍数で、よく使われる数値)を入れておくと良い

◎質問者からの返答

とても参考になります!!!

ありがとうございます!!!

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ