プロが教えるわが家の防犯対策術!

初めまして。情報系の学部に通っている大学生です。
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文で数十回繰り返す
しかし、どちらも同じような所要時間でした。

初心者のため、質問の仕方(情報量など)が不十分かもしれませんが、
お返事いただければ大変うれしいです。
必要ならソースコードも載せさせていただきます。

よろしくお願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (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で受け取れます。

当然それらのことが出来るサーバが必要になりますが。(レンタルサーバとかだと多分動かない。)
    • good
    • 0
この回答へのお礼

お返事が遅くなりました(^ ^;)
いただいたアドバイスをもとに試行錯誤を重ねた結果、
おかげさまで少しずつ改善しています。
ありがとうございました!!

お礼日時:2011/01/03 03:40

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でやってみようかと思います。
他にオススメの言語があれば、是非お教えいただけないでしょうか。

補足日時:2010/12/25 14:44
    • good
    • 0

データベースで数万件のデータは普通なので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次元配列です。

配列やデータのサイズは大きいですが、これはどうしても避けられないのです。
配列やデータは必ずこの大きさ、という前提のもと、何とかサクッと処理できないでしょうか。

補足日時:2010/12/25 14:26
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qpingでポートの指定

pingでIPアドレスを指定して、通信できるかどうかというのは
よく使いますが、pingでポートを指定して応答するかどうかは調べられるのでしょうか?

よろしくお願いします

Aベストアンサー

pingを含むICMPというプロトコルは、OSIの7レイヤで言うところのL2(同一セグメント内通信)とL3(IPルーティングされた通信)の両方にまたがる、ちょっと珍しいプロトコルです。

IPアドレスは指定できますが、別サブネットに属するIPアドレスに到達できればL3通信、できなければゲートウェイと呼ばれる同一サブネットに属する中継装置からの回答を得るという点でL2(MAC通信ではなく、同一セグメント内通信という意味)通信です。

ポート番号はL4で使用されるアドレスですから、L4機能の疎通確認はping(を含むICMP)ではできません。

FTPの疎通確認であれば、クライアントからサーバに対するTCP/21通信(FTP-CMD)が可能であること(サーバからクライアントへのTCP/21からの応答を含む)+サーバからクライアントに対するTCP/20通信(FTP-DATA)が可能であること(クライアントからサーバへのTCP/21からの応答を含む)が必要でしょう。

監視ソフトによるものであれば、
・クライアントからサーバへのログイン(TCP/21)
・クライアントからサーバへのlsの結果(TCP/20)
で確認すればよいでしょう。

pingを含むICMPというプロトコルは、OSIの7レイヤで言うところのL2(同一セグメント内通信)とL3(IPルーティングされた通信)の両方にまたがる、ちょっと珍しいプロトコルです。

IPアドレスは指定できますが、別サブネットに属するIPアドレスに到達できればL3通信、できなければゲートウェイと呼ばれる同一サブネットに属する中継装置からの回答を得るという点でL2(MAC通信ではなく、同一セグメント内通信という意味)通信です。

ポート番号はL4で使用されるアドレスですから、L4機能の疎通確認はping(を含む...続きを読む

QFatal error: Class 'Config' not found

新しい configファイルを作りたいですけど、Fatal error: Class 'Config' not foundのメッセージが出てきた。どうやって設定した方がいいですか?
require_once ('Config.php');
$conf = new Config;
$root = & $conf->parseConfig('config.ini','IniFile');

Aベストアンサー

>> あるいは、カレントパスに Configパッケージと同名のファイルを置いていませんか?

上記についてはどうですか?
あるいは、インクルードパスのいずれかに、Configパッケージ以外の
Config.phpファイルが存在していませんか?

require_once ('Config.php'); の行を
下記のようにフルパスにかえたらどうなりますか
require_once ('/usr/local/php/pear/share/pear/Config.php');
注)Congif.phpのパスはあなたの環境に合わせてください

Q宜しくお願いします。

宜しくお願いします。
mix~max値の間、発行したクエリーからの値を配列に入れたいのですが、どうもFor文中にmin,max値は届いているのですが,$resultに値が入りません。
エラーからしてSQLで行っている変数処理に$iの値が届いてない感じがするのですが、下記のソースを見て頂いて、疑わしき点などご指摘、ご教授いただけませんでしょうか。

どうぞ宜しくお願いします。


--エラー文ここから--->
Catchable fatal error: Object of class stdClass could not be converted to string in ...




--ソースここから--->

$min = h($r -> x);
$max = h($s -> y);
for($i=$min ; $i<= $max; $i++){
$search = sprintf("SELECT id FROM Sheet WHERE no='%d'",$i);
$q_search = mysql_query($search);
$result = mysql_fetch_object($q_search);
echo $result;
}

宜しくお願いします。
mix~max値の間、発行したクエリーからの値を配列に入れたいのですが、どうもFor文中にmin,max値は届いているのですが,$resultに値が入りません。
エラーからしてSQLで行っている変数処理に$iの値が届いてない感じがするのですが、下記のソースを見て頂いて、疑わしき点などご指摘、ご教授いただけませんでしょうか。

どうぞ宜しくお願いします。


--エラー文ここから--->
Catchable fatal error: Object of class stdClass could not be converted to string in ...




--ソースここから...続きを読む

Aベストアンサー

PHPあまり詳しくないので間違っていたらすいません。


>$result = mysql_fetch_object($q_search);
でresultはobject型で代入しておりそれを表示するときにString型に変換できていないのが原因かとおもわれます。

参考URL
mysql-query
http://php.net/manual/ja/function.mysql-query.php

mysql-fetch-array
http://php.net/manual/ja/function.mysql-fetch-array.php

mysql_fetch_object
http://phpspot.net/php/man/php/function.mysql-fetch-object.html


人気Q&Aランキング