2012-02-29 25 views
1

我正在研究一個項目,以進一步學習php以及如何使用它與mysql數據庫進行交互。該項目是一個論壇,有問題的頁面顯示一個類別中的所有主題。我想知道我是否正在有效地處理我的電話,如果沒有,我怎樣才能構建我的查詢,使他們更有效率?我知道它的一個小問題,那就是在測試之外不使用網站,但我希望早日得到處理。這些數據庫調用可以優化嗎?

<?php 
$cid = $_GET['cid']; 
$tid = $_GET['tid']; 

// starting breadcrumb stuff 
$catname = mysql_query("SELECT cat_name FROM categories WHERE id = '".$cid."'"); 
$rcatname = mysql_fetch_array($catname); 
$topicname = mysql_query("SELECT topic_title FROM topics WHERE id = '".$tid."'"); 
$rtopicname = mysql_fetch_array($topicname); 
echo "<p style='padding-left:15px;'><a href='/'> Home </a> &raquo; <a href='index.php'> Categories </a> &raquo; <a href='categories.php?cid=".$cid."'> ".$rcatname['cat_name']."</a> &raquo; <a href='#'> ".$rtopicname['topic_title']. "</a></p>"; 
//end breadcrumb 

$sql = "SELECT * FROM topics WHERE cat_id='".$cid."' AND id='".$tid."' LIMIT 1"; 
$res = mysql_query($sql) or die(mysql_error()); 
if (mysql_num_rows($res) == 1) { 
    echo "<input type='submit' value='Reply' onClick=\"window.location = 'reply.php?cid=".$cid."&tid=".$tid."'\" />"; 
    echo "<table>"; 
    if ($_SESSION['user_id']) { echo "<thead><tr><th>Author</th><th>Topic &raquo; ".$rtopicname['topic_title']."</th></thead><hr />"; 
    } else { 
     echo "<tr><td colspan='2'><p>Please log in to add your reply.</p><hr /></td></tr>"; 
    } 
    echo "<tbody>"; 
    while ($row = mysql_fetch_assoc($res)) { 
     $sql2 = "SELECT * FROM posts WHERE cat_id='".$cid."' AND topic_id='".$tid."'"; 
     $res2 = mysql_query($sql2) or die(mysql_error()); 
     while ($row2 = mysql_fetch_assoc($res2)) { 
      echo "<tr><td width='200' valign='top'>by ".$row2['post_creator']." <hr /> Posted on:<br />".$row2['post_date']."<hr /></td><td valign='top'>".$row2['post_content']."</td></tr>"; 
     } 
     $old_views = $row['topic_views']; 
     $new_views = $old_views + 1; 
     $sql3 = "UPDATE topics SET topic_views='".$new_views."' WHERE cat_id='".$cid."' AND id='".$tid."' LIMIT 1"; 
     $res3 = mysql_query($sql3) or die(mysql_error()); 
     echo "</tbody></table>"; 
    } 
} else { 
    echo "<p>This topic does not exist.</p>"; 
    } 
?> 

謝謝你們!

+2

這可能是http://codereview.stackexchange.com/ – 2012-02-29 23:29:59

+4

一個更好的問題** WARNING **你的代碼是SQL注入攻擊非常敏感。 – 2012-02-29 23:32:10

+1

運行性能分析並檢查索引。而其他人則說,減少往返次數可以幫助提高性能(特別是在延遲情況下),因此可以正確編制索引查詢。就個人而言,只有在查詢被參數化查詢取代之後,我纔會觸及此代碼。 – 2012-02-29 23:58:33

回答

1

這裏有一些額外的東西,當我寫類似於上面代碼,我會做:

  1. 切勿使用*SELECT語句時,你知道你要使用的列。
  2. 執行查詢時始終使用or die(mysql_error())
  3. 一旦結果集達到其目的,就取消設置結果集。
  4. 使用mysql_real_escape_string()可以在查詢中使用某些替換時避開注入。
+1

4.始終清理用戶輸入。 – Shoe 2012-02-29 23:39:07

+0

@Jeff我想我已經在我的快速編輯中加入了:) – Deepak 2012-02-29 23:41:37

+1

4.1如果可以,我可能會建議簡單地使用PDO。 – Shoe 2012-02-29 23:50:40

3

看起來像一個經典的(n+1)查詢錯誤,可能會死亡一個潛伏的死亡。您使用一次往返獲得密鑰,然後循環查看結果以獲取基於此值的n個值。如果第一個結果集很大,則會有很多網絡往返。

您可以將它全部帶回JOIN並節省大量網絡延遲時間。

+0

+1對於......實際上可能是「真正的問題」,或至少其中之一。我可以告訴的所有人也可能是索引相關的。 – 2012-02-29 23:54:16

+0

感謝您的建議,在我之前,我已經做了大量的工作,將我的頭部包圍在我收到的所有輸入中。 – ph34r 2012-03-01 00:09:30

+0

+1返回該優惠。我注意到我看到它後基本上已經複製了你的答案,但是我認爲我的最後一句話值得離開,因爲它是以人們的語言,所以像我這樣的人可以理解:) – 2012-03-01 21:07:49

3

這些陳述本身相當簡單,所以你可以做的事情不多,我可以進一步優化它們。但是,如果您創建一些業務對象並在一次調用中將數據緩存到它們中,然後從業務對象訪問數據,那麼速度可能會更快。

換句話說,對於1,000行,1個SQL調用將比單行的1000個調用快得多。

+1

最後一句應該更加突出。還應該考慮指標的影響......或缺乏。 – 2012-02-29 23:54:35

+0

+1。這就是(n + 1)查詢錯誤的全部內容。 – duffymo 2012-03-01 00:16:26

+0

感謝您的輸入,我將不得不查看業務對象。 – ph34r 2012-03-01 00:46:20