2009-05-03 13 views
0

PHP/MySQLを使用しているクライアントのオンラインカレンダーを作成しています。PHP:whileループのmysql_fetch_array()が時間がかかりすぎる

私は<table><tr>を開始してから、その月の最大日数まで毎日新しい<td>を作成するwhileループを作成しました。

PHPは、$i(カウンタ)の値とデータベースのその行内の書式化されたUnixタイムスタンプの値を比較することにより、MySQLデータベースでその日に発生したイベントを検索します。一致したときにのみ内部行カウンタをインクリメントするために、別のwhileループを作成して結果の新しい配列を取り出します。それはローディング時間を大幅に遅くしています。

ここでは、不要なものを読む必要はありませんので、短縮コード、です:

$qry = "SELECT * FROM events WHERE author=\"$author\""; 
$result = mysql_query($qry) or die(mysql_error()); 

$row = mysql_fetch_array($result); 

for ($i = 1; $i <= $max_days; $i++) { 

    echo "<td class=\"day\">"; 

    $rowunixdate_number = date("j", $row['unixdate']); 

    if ($rowunixdate_number == $i) { 
     while ($rowunixdate_number == $i) { 
      $rowtitle = $row['title']; 
      echo $rowtitle; 
      $row = mysql_fetch_array($result); 
      $rowunixdate_number = date("j", $row['unixdate']); 
     } 
    } 

    echo "</td>"; 

    if (newWeek($day_count)) { 
     echo "</tr><tr>"; 
    } 
    $day_count++; 

} 
+0

forループの条件の周りにコードが壊れているようです。修正してください。 – Oddthinking

+0

なぜフェッチがあなたのコードをそんなに遅くしているのか分かりませんが、私は、あなたがSQLに 'ORDER BY unixdate'節を置かない限り、あなたはそれらを順序で取得することは保証されていないことを指摘したいと思いますあなたは欲しい。 –

+2

PHPの代わりにMySQLで日付チェックを使用しない特別な理由はありますか? –

答えて

1

あなたはそれがかかる時間の長さを表示するにMySQLのツールで、そのクエリを実行したが?

著者列にインデックスがありますか?

PHPに問題はありません。私は、クエリが問題であり、インデックスが原因ではないと思われます。

+0

私はそれをテストする時間がありません。そのための良いツールは何ですか? 作成者の列にはインデックスが作成されません。列属性に単に「INDEX」を追加するだけですか? –

+0

http://dev.mysql.com/downloads/gui-tools/5.0.htmlをお試しください。 Webベースのmysql管理者、Navicatなどがあります。 – cletus

0

「author」はIDですか?または文字列ですか?どちらの方法でもインデックスが役立ちます。

クエリは遅くはない、forループは問題の原因となっています。それは完全ではありません。 $ iループ条件とインクリメントがありません。それとも、これはタイプミスですか?

なぜあなたはその日までにクエリを注文しないのですか?

SELECT * FROM events WHERE author=? ORDER BY unixdate ASC 

、あなたのテーブルの元の日付でグループのイベントに必要なロジックを持つことにしている現在の日付を格納する変数を持っています。すべてのイベント行に同じ日付の同じ色を与えます。

$currentDate = 0; 
while(mysql_fetch_array($result)){ 
    if($currentDate == $row['unixdate']){ 
     //code to present an event that is on the same day as the previous event 
    }else{ 
     //code to present an even on a date that is past the previous event 
     //you are sorting events by date in the query 
    } 

    //update currentDate for next iteration 
    $currentDate = $row['unixdate']; 
} 

unixdateは、イベント時間が含まれている場合、その後、あなただけを抽出するためにいくつかのロジックを追加する必要があります。日付は、イベントの時間を考慮していない、あなたはこれを行うことができ、UNIXタイムスタンプであると仮定すると、

unix date timestmap - 時間と分を除く。

あなたの代わりに1つのクエリの31個のクエリを、やっているので、NaelエルShawwaが指摘したようにあなたは、HTMLテーブルを構築

2

遅さに役立ちます希望が最も可能性が高いです - あなたがしようとしている場合その月の特定の著者の今後のイベントをすべて取得するには、1つのSQLクエリでそれを選択し、結果セットを反復処理して実際にテーブルを生成する必要があります。例えば。

$sql = "SELECT * FROM events WHERE author = '$author' ORDER BY xdate ASC"; 
$rsEvents = mysql_query($sql); 
echo("<table><tr>"); 
while ($Event = mysql_fetch_array($rsEvents)) { 
    echo("<td>[event info in $Event goes here]</td>"); 
} 
echo("</tr></table>"); 

さらに、SQLクエリとHTML生成を混在させるのは悪い考えです。外部データは1つの場所に集められ、出力データは別の場所で生成されます。私の例では、HTML生成の直前にSQLを置くことで、それを近づけることができますが、HTMLブロックに真ん中でSQLクエリが含まれているよりも優れています。

+0

ループ内のループは、通常、かなり悪い考えです。 @dirtsideによれば、おそらく単一のSQLクエリでもそれを行うことができます。 –

1

上記のコメント以外にも、これはパフォーマンス上の問題の最も一般的な原因の1つであるため、SQLクエリを最適化しようとします。

letが

は " SELECTを行うために、あなたはタイトル、日付、宣伝文、コンテンツ分野でニュース記事のテーブルを持っていて、タイトルだけを取得し、HTMLページのリストとしてそれらを表示する必要があると言います* FROM TABLE " は、ループを実行する際にDBサーバーがすべてのフィールドデータを取得することを要求していることを意味します(使用しないBlurbとContentを含む)。

次のようなものにすることをを最適化する場合:

SELECTタイトル、TABLEから日付」必要なデータのみを取得しますし、サーバーの使用率の面で、より効率的です。

私はこれがあなたを助けてくれることを願っています。

関連する問題