初めまして。情報系の学部に通っている大学生です。
phpmyadminを使っています。
早速ですが、以下について質問です。
・データベースの1つのテーブル(3000行)から、データを取り出す
・それをもとに、(0,1など1ビットの)データを、4000行×72000列の配列に格納
これを実践するプログラムを作成したところ、作業完了に相当な時間を要します。
「php.ini」のタイムリミットを、デフォルトの60秒から18000秒(5時間)に変更しても足りないほどです。
そもそも、たかだか 1ビット×4000×72000 = 288,000,000ビット = 36MB(?)を扱うのに
何時間もかかるわけないですよね?
個人的には、配列の大きさ(4000行×72000列)や、データベースから取り出す行の数(3100行)が
比較的大きいのがミソかな、と感じています。
ちなみに、データベースにアクセスする回数が多いと動作も遅くなるのか、と思い、
データベースからデータを取り出す処理を、以下の2パターン試しました。
1. 「SELECT * FROM xx 」 により、一度に3000行すべて取り出す
2. 「SELECT * FROM xx WHERE yy = zz」により、取り出すデータを分ける。
これをfor文で数十回繰り返す
しかし、どちらも同じような所要時間でした。
初心者のため、質問の仕方(情報量など)が不十分かもしれませんが、
お返事いただければ大変うれしいです。
必要ならソースコードも載せさせていただきます。
よろしくお願いいたします。
No.3ベストアンサー
- 回答日時:
私も他の言語はあんまり触ってこなかった悪い子なので、オススメの、と言われるとなんとも言えないのですが、
とりあえず質問者さんがやったことのあるCとかJavaで試してみてはいかがでしょう。左記のものは、スクリプト言語ではないので、ソレよりは高速です。
PHPには、system関数とかexec関数といったものがあって、OSのコマンドを叩くことが出来ます。
http://jp2.php.net/manual/ja/function.exec.php
http://jp2.php.net/manual/ja/function.system.php
<?php
//execでCやJavaで書いたプログラムを叩く
//例はとりあえずWindowsのdirコマンド
exec('dir', $output);
//$outputには実行後に、標準出力が「\n」で区切られた配列で渡ってくる。
print_r($output);
?>
dirとしたところを、各言語のコマンドラインの実行で、やってみると。
そうすると、別の言語で処理を行って、結果を再度文字列で、ですがPHPで受け取れます。
当然それらのことが出来るサーバが必要になりますが。(レンタルサーバとかだと多分動かない。)
お返事が遅くなりました(^ ^;)
いただいたアドバイスをもとに試行錯誤を重ねた結果、
おかげさまで少しずつ改善しています。
ありがとうございました!!
No.2
- 回答日時:
PHPには、BIT型が無いので、1,0にしてみても、ソレはIntegerとなり、少なくとも8bitは消費するのではないでしょうか。
そして、PHPの配列はメモリ食います。
とりあえず、少なくとも4000行×72000列の値は常に「1」が含まれている配列を生成してみると、
<?php
echo "MEMORY0 : " . number_format(memory_get_usage()) . " byte(初期値)<br>";
$result = array();
for($i=0; $i<4000; $i++){
for($j=0; $j<72000; $j++){
$result[$i][$j] = 1;
}
}
echo "MEMORY1 : " . number_format(memory_get_usage()) . " byte(配列生成)<br>";
unset($result);
echo "MEMORY5 : " . number_format(memory_get_usage()) . " byte(配列解放)<br>";
?>
PHPのmemory_limitを512MBまであげても、途中でエラーでこけます。
この手の演算は、PHP(とか他のスクリプト言語)で扱うような事柄ではない気がします。
この回答への補足
hogehoge78さん、
ご回答ありがとうございます!
なるほど、PHPだと0,1でも8bit消費してしまうんですね。。。
早速、ご回答いただいたソースコードを「goo_answer.php」として
実行させていただいたところ、以下のエラーが返ってきました。
------------------------------------------------
MEMORY0 : 316,680 byte(初期値)
Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 262144 bytes) in C:\xampp\htdocs\goo_answer.php on line 8
------------------------------------------------
メモリ上限値を512MBに引き上げてもエラー…となると、
やはりPHPとしては限界なのでしょうか。。。
私自身はCとJavaを授業で学習したことがありますが、他の言語は初めてです。
Cや(アプレットなどでなく普通の)Javaは、スクリプト言語じゃないですよね?
配列処理の部分は、一度Cでやってみようかと思います。
他にオススメの言語があれば、是非お教えいただけないでしょうか。
No.1
- 回答日時:
データベースで数万件のデータは普通なので3000程度であれば普通は問題ないですね
プログラムの途中でファイルに時間を記録するようにしてどの部分が時間がかかるか調べてみては
質問はPHPとMySQLのことでphpmyadminは今回の件とは関係ないですよね
この回答への補足
php504さん、
早速のご回答、ありがとうございます!
おっしゃる通り、phpmyadminでなくPHPとMySQLの問題ですね。
誤解を生じる表現を使ってしまい、反省しております。。。
早速「プログラムの途中でファイルに時間を記録する」方法を実践させていただきました。
ある箇所でtxtファイルに現在時刻を出力するよう設定したところ、
以下の部分が、1分間で平均2,3回しか処理できていないことが分かりました。
for(a=0; a<100; a++) {
for(b=0; b<31; b++) {
for(c=0; c<100; c++) {
for(d=0; d<744; d++) {
・配列Hからデータを取得
・配列Hのデータ(zz)をもとにDBからデータを取得
("SELECT xx FROM yy WHERE zz")
・DBのデータをもとに、配列I、配列J、配列Kについて、
データを取得または格納
}
}
この時点でtxtファイルに現在時刻を出力
}
}
txtファイルには本来、「現在時刻」が3100回保存されるはずですが、
実際はその3割弱の887回しか保存されていませんでした。保存された「現在時刻」から、
888回目でタイムアウト(php.iniで設定した18000秒=5時間)を迎えたことが分かります。
ちなみに、
配列Hは100*744(=74400)の2次元配列、
配列Iは100*31*24(=74400)の3次元配列、
配列J、Kはともに100*31(=3100)の2次元配列です。
配列やデータのサイズは大きいですが、これはどうしても避けられないのです。
配列やデータは必ずこの大きさ、という前提のもと、何とかサクッと処理できないでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- MySQL 書籍の内容はまともでしょうか? 1 2023/01/22 03:07
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- Visual Basic(VBA) access count数を変数に格納 2 2022/03/30 19:21
- MySQL 複数DBテーブルからのデータ取得 3 2022/05/17 15:02
- JavaScript Q&Aの掲示板を作成していてヤフー知恵袋やgoo質問のように質問ごとにURLを生成したい 5 2023/08/04 01:22
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- Excel(エクセル) エクセルで沢山のレコードの最後に追記するには? 7 2023/04/10 13:27
- その他(データベース) 業務用のデータベースサーバーの選び方について 4 2022/11/22 10:22
- MySQL 【投稿情報用データベース posts】は必要ないと思います。 1 2022/06/02 21:25
- その他(データベース) pythonでsqlight勉強中、クエリー結果の利用法教えて下さい 1 2022/04/28 20:38
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
foreachのなかで次のキーを参照...
-
String だと「 ByRef引数の型が...
-
$_SESSIONに二次元配列を使える...
-
PHPのカッコ[ ]の使い方について
-
OCI で、SELECT結果行数を取得...
-
【Smarty】foreach関数やsectio...
-
漢字のソートについて
-
file_existsでファイル名の部分...
-
PHPのPOSTでの半角スペース
-
プルダウンメニューでCSVデータ...
-
配列をループでたくさん宣言し...
-
STLのvectorで作った配列をメン...
-
読み(あ行~わ行)ごとに分け...
-
エラーメッセージ(無効な間接...
-
PHPでCSVの一部の行を編集したい
-
rubyで複数列のデータを一行に...
-
CSVデータの行数カウントをした...
-
行列
-
配列の要素(value)に、変数を...
-
別ファイルの構造体の値を読み...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
配列をループでたくさん宣言し...
-
$_SESSIONに二次元配列を使える...
-
file_existsでファイル名の部分...
-
String だと「 ByRef引数の型が...
-
foreachのなかで次のキーを参照...
-
配列を回すとき、最後の要素だ...
-
PHPのカッコ[ ]の使い方について
-
PHPのPOSTでの半角スペース
-
セッション配列の取得の仕方
-
PHPにてクラスを配列にすること...
-
配列一致(要素順番は違うが内容...
-
PHP 多次元配列変数のデータ受...
-
漢字のソートについて
-
unset使用時の利点
-
OCI で、SELECT結果行数を取得...
-
postgresql関数をつかったレコ...
-
配列をmysqlに保存
-
あいまい検索
-
チェックボックス複数選択 mys...
-
総当り表
おすすめ情報