【问题标题】:Am i being very inefficient ? mysqli call in loop我效率很低吗? mysqli 循环调用
【发布时间】:2016-05-18 13:52:10
【问题描述】:

我有一个包含 2 个表的数据库,我在 items 表中有一个主键(item_id)和一个外键(color_id)。我列出的项目以颜色作为标题如下,

商品详情

//item_id

//color_id

//详情

颜色

//颜色标识

//颜色后缀

//颜色细节

我列出了这些项目 颜色后缀(RE) 商品详情 商品详情 项目详情等...

颜色后缀(RT) 商品详情 商品详情

为此,我循环遍历颜色表并在每次循环时调用 sql

$query = "SELECT * FROM COLORS";
$result = mysqli_query($connection,$query);
while($data= fetch_array($result)){
    echo "<h2>{$data['color_suffix']}</h2>";
    $query2 = "SELECT ... FROM items WHERE color_id = {$data['color_id']}";
    $result2 = mysqli_query($connection,$query);
    while($item = fetch_array($result2)) {
        //List all items
    }
}

这只是一种 sudo 代码,我只是想知道是否有更有效的方法。 我一直在阅读 SQL 内连接,这是我应该使用的方法吗?

我也阅读了准备好的语句,但老实说,我并不真正理解其中的语法。

我应该这样做吗?还是效率极低?请记住,将有大约 30 种不同的颜色,然后每个大约 10 - 50 个项目,以便进行大量 SQL 调用。

有人可以提供一些非常基本的 sudo 代码来帮助我了解如何实现这一目标吗?

提前谢谢你 瑞恩

【问题讨论】:

  • 1+1n 个 SQL 请求几乎肯定会比 1 个 SQL 请求慢,尤其是随着 n 值的增加

标签: php mysql mysqli prepared-statement inner-join


【解决方案1】:

你可以用一个简单的内部连接来做到这一点:

SELECT * FROM colors, items WHERE colors.color_id = items.color_id

http://dev.mysql.com/doc/refman/5.7/en/join.html

【讨论】:

  • 你能快点用 sudo 说明我将如何循环吗?没想到这么简单?谢谢你
  • 输出和你做的一样,只是现在你被简化为一个循环。
  • 我刚刚完成的查询完美运行,虽然我无法以与我相同的方式显示,但我设法让它输出 color suffix //Item number (same as last color suffix) //商品编号等我想要的是有 Color Suffix //商品编号 //商品编号 //商品编号 下一个Color Suffix //Item number //Item Number 我使用的循环是'while($data = fetch_array($result)) { echo "

    {$data['suffix']

    " ; echo "$data['item_number']; } 我不明白 id 如何在没有循环的情况下做到这一点?
  • 您获取的新结果包含项目列和颜色列。尝试运行“print_r($data);”看看里面有什么。
【解决方案2】:

使用连接。然后为您的分组添加一点逻辑。

 $query = "SELECT ... FROM COLORS, ITEMS WHERE items.color_id = colors.color_id order by colors.color_id";
 $stmnt = $db->prepare($query);
 $stmnt->bind_results($color_id, $color_suffix, ...);
 $stmnt->execute();
 $cur_col_id = '';
 while($stmnt->fetch())
 {
   if($color_id !== $cur_col_id)
   {
     echo '<h2>' . $color_suffix . '</h2>';
     $cur_col_id = $color_id;
   }
   //print the items here, no second loop.
 }

请记住 ... 不应该只是一个 *,它应该是您将使用的实际字段的列表。该顺序必须与 bind_results 调用中的顺序相匹配。您还应该添加错误检查和处理。

【讨论】:

  • 谢谢,这很有意义。真的很感激