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

PHP & MySQL

MySQLを使った掲示板を作成しています。

index.php ではまず20件ずつ各トピックス名や前トピック数、最終更新時間、未回答件数などを表示しています。しかし表示する物が多く一度に異なったSQLを5?6ほどはいて検索させ、表示しています。

また、各トピックの表示はindex.phpではなく topic.phpに任せているのですが、ここでも数個のSQLがあります。

---
$sql = "select * from `bbs` ....
$res = mysql_query($sql,$connection);

$sql2 = "select `name` from....
な感じです。

しかし、index.phpとtopic.phpを何回も早い感じでリンクを進んだり戻ったりしていると急に表示されなくなり、更新しても表示されません。そして数分後、再度更新すると普通に表示されます。

たぶんSQLなどを大量にはいたり、組み方が下手なせいだと思いますが、なにかいい改善方法などないでしょうか?よろしくお願いします。

PS:phpbbなどを使えばいいなどの回等は不要です。またあまりオブジェクト指向に関しては理解していません。

●質問者: esecua
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:BBS INDEX MySQL name PHP
○ 状態 :終了
└ 回答数 : 5/5件

▽最新の回答へ

1 ● ito-yu
●10ポイント

それはMySQLの同時接続数制限に引っかかっているに違いありません

http://www.y2sunlight.com/ground/?MySQL4.1%2F3.MySQL%A5%B5%A1%BC...

SQLをもっと整理して、一画面表示するのに2?3回のクエリで済むような設計にするのが一番良いと思うのですが、ソースを見ないことには具体的なアドバイスは難しいですね。

phpbbを使え、とは言いませんが、phpbbのソースを見て勉強してみてはいかが?w

◎質問者からの返答

回答ありがとうございます。

もしよろしければ「SQLをもっと整理して、一画面表示するのに2?3回のクエリで済むような設計にするのが一番良い」に関して再度アドバイスお願いします。

ソースですが全て載せれないのでSQL周りを載せます。

if (!$conn = mysql_connect($host, $user, $password)){die("接続できません");}

mysql_select_db($name, $connection);

$sql = "SELECT * FROM `bbs` WHERE `new` = '".$newid."' ORDER BY `number` DESC";

$res = mysql_query($sql,$connection);

$sql2 = "SELECT * FROM `bbs` WHERE `day` = '".$dayid."';";

$res2 = mysql_query($sql2,$connection);

$sql3 = "SELECT * FROM `bbs` WHERE `keyword` = '".$word."' AND `$id->check` = 'OK';";

$res3 = mysql_query($sql3,$connection);

$sql4 = "SELECT * FROM `bbs` WHERE `public` = '".$publicid."';";

$res4 = mysql_query($sql4,$connection);

$row4 = mysql_fetch_object($connection);

こんな感じでたくさんのSQLを吐いています。一部ADOBDも使用して接続、検索しています。

これを接続制限に引っかからないように整理する方法を伝授願います。


2 ● pxb12663
●15ポイント

肝心のソースがないので、具体的に何がやりたいのかよくわかりませんが、SQL構文のINNER JOINやLEFT JOINを活用すればスッキリしそうな気がします。

テーブルの結合ですね。リレーショナルDBならではの機能です。

http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/mysql_09.htm

ここを参考に頑張ってみてください。難しそうですが、慣れればたいしたことないです。


3 ● ito-yu
●7ポイント

では再回答を。長いSQLですが

$sql = "SELECT 'NEW' AS rectype,* FROM bbs WHERE new = '{$newid}' UNION SELECT 'DAY' AS rectype,* FROM bbs WHERE day = '{$dayid}' UNION SELECT 'KWD' AS rectype,* FROM bbs WHERE keyword = '{$word}' AND {$id->check} = 'OK' UNION SELECT 'PUB' AS rectype,* FROM bbs WHERE public = '{$publicid}' ORDER BY type,number DESC";

とか、複数のSELECT結果をUNIONして取得します。rectypeていうカラムでそれぞれのレコードがどの条件なのかわかります。

ちなみにMySQLってバッククォート必須なんですか?無くてもいけると思って消しちゃいましたのでこのままではエラーになるかも。です。

◎質問者からの返答

ん?でもちょっとまてくださいよ。1個のSQLで叩いたとしてもデータと取得はどのように行うんですか? たとえば array['topic'] とした場合全てのSQLでの結果でのtopicカラムが表示されてしまいそうな感じがしますが。

あと、SQLですがなぜかエラーがでます。


4 ● falcosapiens
●28ポイント

$res = mysql_query($sql,$connection);

(毎回link identifierを指定している)

を繰り返しているために毎回接続を開いていますね。

各スクリプトの最初の1度目を除いて

$connectionを削ってみると良いかと思います。

$res = mysql_query($sql);

という感じで。

http://php.s3.to/man/function.mysql-query.html

◎質問者からの返答

なるほど


5 ●
●40ポイント ベストアンサー

SQLの列名などから想像するに

  1. incrementされるnewidの降順 (新しい発言の取得?)
  2. 日付指定
  3. 特定のキーワードを含むもの
  4. 公開設定による絞込み (public)

といったような5つの検索を行っているように思えるのですが、1つのページにはどのような情報を掲載しているのでしょうか。

全て1つのページのためのSQLだとしたら、何か問題があるような気がします。

複数のテーブルから色々な情報を取得しており、それぞれが独立した情報の場合、SQLが多くなるのは仕方ありませんが、全て同じテーブルを対象にしていますよね。

普通、1回か2回のSQL文でなんとかなるはずです。

表示画面のイメージがもう少し明らかになるとより的確な回答がつくのではないかと思います。

また、質問文中に「20件ずつ」表示している、という記述がありましたが、この20件というのはどのように指定していますか。

上記のSQLにはLIMITやOFFSETによる指定がないようでしたので、このままでは全件データを取得してしまいます。

もし現時点でLIMITを使っていないのであれば、LIMITを使うだけで大幅に改善すると思います。

LIMIT 節を使用すると、SELECT ステートメントで返されるレコード数を制限することができる。LIMIT は 1 つまたは 2 つの数値引数を取る。これらの引数は整数定数でなければならない。

[参考URL]

また、最後のチューニングの部分になりますが、SQLのSELECTにてWHERE句で指定する列についてはINDEXを張っておくと検索速度が著しく向上します。

他にはSELECTで選択する列をアスタリスク(*)指定せずに、本当に必要な列だけに限定することで、いくらか速度は向上すると思います。

参考になれば幸いです。

◎質問者からの返答

bonlifeさん、いつもありがとうございます。

関連質問


●質問をもっと探す●



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