8

我在公司内部就这件事的循环查询进行了内部辩论:

$sql = "
  SELECT foreign_key
  FROM t1";

foreach(fetchAll($sql) as $row)
{
  $sub_sql = "
    SELECT *
    FROM t2
    WHERE t2.id = " . $row['foreign_key'];

  foreach(fetchAll($sub_sql) as $sub_row)
  {
    // ...
  }
}

而不是像这样使用 sql 连接:

$sql = "
  SELECT t2.*
  FROM t2
  JOIN t1
  ON t1.foreign_key = t2.id";

foreach(fetchAll($sql) as $row)
{
  // ...
}

关于这一点的附加信息,数据库很大,有数百万行。

我当然已经搜索了这个问题的答案,但是没有人能以一种好的方式回答这个问题,并且有很多赞成票让我确信一种方式比另一种方式更好。

问题

有人可以向我解释为什么其中一种方法比另一种更好吗?

4

2 回答 2

11

join方法通常被认为更好,只是因为它减少了向数据库来回发送查询的开销。

如果您在表上有适当的索引,那么这两种方法的基本性能将是相似的。也就是说,这两种方法都将使用适当的索引来获取结果。

从数据库的角度来看,该join方法要优越得多。它将数据逻辑整合在一个地方,使代码更加透明。它还允许数据库进行在应用程序代码中可能不明显的优化。

于 2013-08-23T14:12:06.033 回答
8

由于驱动程序开销,循环的效率要低得多

这与我回答的另一个问题相似,但与 cv. 我的完整答案在这里,但我将总结要点:

每当您连接到数据库时,都会执行三个步骤:

  1. 与数据库的连接已建立。
  2. 对数据库执行一个或多个查询。
  3. 返回数据进行处理。

使用循环结构,您最终将产生额外的驱动程序请求开销,每个循环周期都会有一个请求和一个返回,而不是单个请求和单个返回。即使循环查询不比单个大查询花费任何时间(这不太可能,因为 MySQL 内部内置了很多快捷方式来防止使用完整的重复循环),您仍然会发现单个查询更快司机开销。

使用没有 的循环TRANSACTIONS,您还会发现您遇到关系数据完整性问题,其中其他操作会影响您在循环周期之间迭代的数据。再次使用事务会增加开销,因为数据库必须维护两个持久状态。

于 2013-08-23T14:16:16.607 回答