2011-06-27 19 views
1

foreachループ内でSQLクエリを取得しました。時には多くの場合がありますが、いくつかの基準、潜在的に最大78のクエリに応じて、たくさんのクエリを実行することを意味します。このSQLクエリを最適化する

今や、早すぎる最適化はすべての悪の根本原因だと私は知っていますが、私は78のクエリを見たくありません。それは健康ではありません。ここで

はコードです:

$crumbs = explode(",", $user['data']['depts']); 

foreach ($crumbs as &$value) { 
    $data = $db->query("SELECT id FROM tbl_depts WHERE id = '" . $value . "'"); 
    $crumb = $data->fetch_assoc(); 
    $dsn = $db->query("SELECT msg, datetime FROM tbl_motd WHERE deptid = '" . $value . "'"); 
    $motd = $dsn->fetch_assoc(); 
    if ($motd['msg'] != "") { 
     <?php echo $motd['msg']; ?> 
    } 
} 

は、私はそれが少しでもよくすることはできますか?

+0

以下の最適化とは別に、パフォーマンスを向上させるためにストレート・セレクトの代わりにストアド・プロシージャにすることを検討することをお勧めします。 – nickytonline

+0

このコードはSQLインジェクション攻撃に対して脆弱であることに注意してください。 –

+0

こんにちはDaniel、なぜこの場合ですか?データは配列を取得するだけです。配列を入れる前にサニタイズされているはずです。$ user ['data']とその子もこのコードの前に消毒されます。 – bear

答えて

1

使用IN MySQL operatoridのための値のセットを検索する:

$ids = '"' . implode('", "',$crumbs) . '"'; 
$query1 = "SELECT id FROM tbl_depts WHERE id IN (" . $ids . ")"; 
$query2 = "SELECT msg, datetime FROM tbl_motd WHERE deptid IN (" . $ids . ")"; 

をそして、あなたが代わりにのみ2クエリを持つことになりますので、あなたは、あなたがforeachループを使用して必要なすべてのデータを取得する必要はありません例えば、tableという名前のテーブルがあります。このテーブルのIDは、1,2,3,4,5,6,7,8,9,10(自動インクリメント)です。私はIDが1,5,8のレコードが必要であることを知っています。私のクエリは次のようになります。

$sql = "SELECT * FROM `table` WHERE id in (1,5,8);"; 

そして、あなたはあなたが$crubms配列の値を変更しない場合foreachループで&演算子を使用する必要がありますなぜ私は理解していません。

+0

私はこれで上記の2つのクエリを置き換えますが、コード自体を書き換えますか? – bear

+0

私は&演算子を入れているだけの習慣です。 – bear

+0

@Shamil、はい。別の方法を使用しているため、コードを書き直す必要があります。 – Nemoden

1

私はこれがあなたが欲しいと思うと思います。

SELECT msg, datetime 
FROM tbl_depts td 
INNER JOIN tbl_motd tm ON td.id = tm.deptid 
+0

どちらを取り替えるべきですか? – bear

+0

私は本当にクエリのロジックを調べていませんでしたが、あなたはどこかでどこを忘れてしまったと思います。私はOPのクエリの結果は特定のIDのセットによって制限されると思います。 'INNER JOIN tbl_motd tm ON td.id = tm.deptidどこのtd.id()'でしょうか? – Nemoden

+0

はい。私はどこを忘れた。あなたは正しいです –