2012-02-29 6 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/ –

+4

** ПРЕДУПРЕЖДЕНИЕ ** ваш код очень восприимчив к атакам SQL-инъекций. –

+1

Запустите анализ производительности и проверьте индексы. В то время как другие говорили, что сокращение круговых поездок может помочь в производительности (особенно в ситуациях с латентностью), поэтому можно правильно проиндексировать запросы. В личной заметке я бы не касался этого кода до тех пор, пока запросы не будут заменены параметризованными запросами. –

ответ

1

Вот некоторые дополнительные вещи, я хотел бы сделать, когда я пишу код, как выше:

  1. Никогда не используйте * в SELECT заявлении, когда вы знаете, столбцы, которые вы собираетесь использовать.
  2. При выполнении запроса всегда используйте or die(mysql_error()).
  3. Уничтожьте результирующие наборы после того, как результирующие наборы выполнили свою задачу.
  4. Используйте mysql_real_escape_string(), чтобы избежать инъекций при использовании некоторых подстановок в ваших запросах.
+1

4. Всегда дезинфицируйте пользовательский ввод. – Shoe

+0

@Jeff Я думаю, я добавил, что в моем быстром редактировании :) – Deepak

+1

4.1 Я мог бы предложить просто использовать PDO, если можно. – Shoe

3

Похоже, что классическая ошибка (n+1), которая может умереть со скрытой смертью. Вы получаете ключ, используя одну поездку туда и обратно, затем вы обходите результаты, чтобы получить n значений на основе этого. Если первый набор результатов будет большим, у вас будет много сетевых поездок.

Вы можете вернуть все это с помощью JOIN и сэкономить много латентности сети.

+0

+1 Для ... на самом деле получить то, что может быть «реальной проблемой» или хотя бы одним из них. Мог бы также быть индекс, связанный для всего, что я могу сказать. –

+0

Спасибо за предложение, у меня есть много работы впереди меня, чтобы обернуть голову обо всем, что я получил. – ph34r

+0

+1 возвращение в пользу.Я заметил, что я в основном скопировал ваш ответ после того, как увидел его, но я решил, что последнее предложение мое стоит оставить, так как оно находится в мирянах, поэтому такие люди, как я, могут понять :) –

3

Сами заявления довольно просты, поэтому вы не можете сделать так, чтобы их оптимизировать дальше, чем я знаю. Однако, если вы создаете некоторые бизнес-объекты и кешируете данные в них по одному вызову, а затем получаете доступ к данным из бизнес-объектов, это может быть быстрее.

Другими словами, 1 вызов SQL для 1000 строк будет намного быстрее, чем 1000 вызовов для одной строки.

+1

Последнее предложение должно быть более заметным. Также следует учитывать влияние индексов ... или отсутствие. –

+0

+1 от меня. Вот что такое ошибка (n + 1) запроса. – duffymo

+0

Спасибо за ваш вклад, мне нужно будет изучить бизнес-объекты. – ph34r

Смежные вопросы