ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

ゼロからはじめるPHP講座コミュのPHP側からSQL文を投げてDBから全データが取得できない!!

  • mixiチェック
  • このエントリーをはてなブックマークに追加
困り果てています。
もしお分かりになる方がいらしたら、教えてください。

PHP側からSQL文を投げてDBから全件データを取りたいのですが、

Fatal error: Maximum execution time of 30 seconds exceeded in usr/local/○○/php/Ethna/class/Ethna_△△.php on line ■■

というエラーが出てしまいます。

set_time_limit();の時間が短いのかな?

と思い、実際にDBでSQL文を投げると
1秒ちょっとでデータを取得できます。
(ちなみにset_time_limit();の時間を90まで延ばしましたがNGでした)

PHPのSQL文は

$sql = "select A, B, C, D, E, F ";
$sql .= "from main_table ";
$sql .= "where sex = 2 and blood_type = 1 ";
$sql .= "and mail_addr is not null ";
$sql .= "and length(mail_addr) > 0 ";
$sql .= " {$where_kikan} ";

です。
(これは月別のSQL文です)

{$where_kikan}の部分で、月ごとに分けており
月ごとに分けたもの(ひと月分)は取得できます
が・・
全件が取得できません。

管理画面の上のほうに
リンクで
「月別配信メール」というリンクを作り
それをクリックすると
上記のSQL文で月別のデータが出るのですが
「全件表示」(all)をクリックして

$sql = "select A, B, C, D, E, F ";
$sql .= "from main_table ";
$sql .= "where sex = 2 and blood_type = 1 ";
$sql .= "and mail_addr is not null ";
$sql .= "and length(mail_addr) > 0 ";

とすると、

Fatal error: Maximum execution time of 30 seconds ・・

となってしまいます。

{$where_kikan}
の部分は、

if($_GET['mode'] != "all"){
$where_kikan =
" and date_entry >=
'{$days[year]}/{$days[mon]}/1 0:0:0'
and
date_entry < '{$days[next_year]}/{$days[next_mon]}/1'";
$top_comment =
"<center>
 <font color=navy size=2>
  {$days[year]}年{$days[mon]}月データ
 </font>
 <a href=\"index.html?mail_list=true&mode=all\">
 全件表示
 </a>
 </center>";
 }else{
 $top_comment =
  "<center>
  <font color=navy size=4>
  全件データ
  </font>
  </center>";
 }

かなりあせっていて、質問の仕方がおかしかったら申し訳ありません。

このソースは前任の方が作ったもので、今エラー修正をしている最中です。

フレームワークは初めての上に、
納期が迫ってとっても困っています。

DBからはデータが取得できるのに、
PHPから取得できないのって、どんな時なのでしょうか?

もしよかったら教えてください。
よろしくお願いいたします。



コメント(12)

ドキュメントをよく読みましょう。

多分。

でも、いったい何件あるデータを取得してるんですか?
ブラウザが固まりそうな気もしますが。。。

ページングするなりして、limitできないのでしょうか?

ちなみに、Ethnaでは、そのあたりは全くいじっていないはずです。
CLIの場合に制限を解除してるくらいですね。。。
タイムアウトでしょ。。。きっと。。。
max_execution_time の初期値が30だからなのかな?
変更できればいけそうですが。。。

参考サイト
http://jp.php.net/manual/ja/ref.info.php#ini.max-execution-time

http://jp.php.net/manual/ja/function.set-time-limit.php
配列に全件読み込んでからhtmlを出力しようとすると、ディスクスワップが大量に発生してタイムアウトしやすいけれど。

こんな単純なのじゃないかな。
皆様ありがとうございます。
未だにエラーは解決されず、途方に暮れています・・

>どのようにクエリーを投げていますか?

クエリは
$result = $○○_db->query($sql);
とし、
そのあとループでDBから1行づつデータを抽出しています。
while( $r = $result->fetchRow(DB_FETCHMODE_OBJECT) )
{
 for($i=1;$i<=5;$i++){
  $col = "mail_{$i}_code";   preg_match('/l(\d+)s/',$r->$col,$class);        preg_match('/k(\d+)f/',$r->$col,$ken);
       if($class[1] && $ken[1] &&                $count_check[$r->id_user][$ken[1]][$class[1]] !=      1){
                 $SEND_LIST[$ken[1]][$class[1]]++;
                 $count_check[$r->id_user][$ken[1]][$class[1]] = 1;
 $KEN_ALL[$ken[1]]++;
                 $CLASS_KEN_ALL[$class[1]]++;

 $CLASS_ALL[$class[1]]++;

     $ALL_ALL++;
   }elseif($class[1] && $ken[1] == "" &&         $count_check2[$r->id_user][$class[1]] != 1){ $count_check2[$r->id_user][$class[1]] = 1; $CLASS_ALL[$class[1]]++;
$ALL_ALL++;
}
}
}

どうやら$SEND_LISTなどで取って来ているデータが多すぎてエラーが出てきているようなのですが、
よい解決方法が見つからずに現在に至ります。

>タイムアウトでしょ。。。きっと。。。

set-time-limitで制限時間を90に延ばしても、エラーは出てしまいました。もっと長くしたほうがいいのでしょうか?

>ページングするなりして、limitできないのでしょうか?

ごめんなさい。
ページングに関してはよく分からないので、調べて見たいと思います。

>配列に全件読み込んでからhtmlを出力しようとすると、ディスクスワップが大量に発生してタイムアウトしやすいけれど。

そうなんですね・・。
プログラムを作り直したほうが良いのでしょうか。
あまり勝手に変えられないのですが、考えて見たいと思います。

自分の勉強不足を痛感しています。
もし何か考え違いをしていたら教えて頂けたら嬉しいです。
どうぞよろしくお願いいたします。
http://www.go-pear.org/manual/ja/package.html.pager.php
set_time_limit(0);
echo " ";
ob_flush();
flush();
KEN_ALLって、、もしかして、10数万行ある、
全県郵便番号データ?
引き続きありがとうございます。

ごめんなさい。以下の

>http://www.go-pear.org/manual/ja/package.html.pager.php

>set_time_limit(0);
echo " ";
ob_flush();
flush();

に関して、使い方がよく分かりません。
調べて見たいと思います。

>KEN_ALLって、、もしかして、10数万行ある、
全県郵便番号データ?

説明が足りなくて申し訳ありません。
KEN_ALLは都道府県の県名です。
>>mainauさん

set_time_limit(0);
上記は時間制限を行わない設定です。

ですが上記だけの場合、WEBサーバー側のタイムアウトでブラウザが落ちてしまうので、以下で最初にレスポンスを返してあげています。

echo " ";
ob_flush();
flush();

ただ上記は力技なのでWEBサーバー側のタイムアウトを設定出来るのが一番良いんですがね。

それとですが、取得しようとしているデータ件数がどの程度あるのか明確にしたほうが良いと思います。
皆様ありがとうございました。
結局原因は分からず、他の方に委ねる事となりました。
書き忘れていましたが、
取得しようとしているデータ量は約10万件・・30秒以内に取得できる量らしいので、
SQL文に問題がありそうです・・
これからもっと勉強したいと思います。
お騒がせして申し訳ありませんでした。
貴重なご意見など、ありがとうございました。
SQL文にLIMITを入れて、取得件数を例えば10件などに限定してみてはどうでしょうか。
これでタイムアウトなのかSQLの問題なのか、原因の切り分けが出来ると思います。
あと10万件のデータを全てレコードセットに持つというのはあまり現実的ではないと思いますので、設計を再検討した方が良いかもしれません。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

ゼロからはじめるPHP講座 更新情報

ゼロからはじめるPHP講座のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング