【问题标题】:SQL queries within a loop循环内的 SQL 查询
【发布时间】:2011-01-17 19:59:08
【问题描述】:

Google 代码建议您应避免在循环中使用 sql 查询。原因是多次往返数据库会显着减慢您的脚本速度。他们给出的示例查询是这样的。

$userData = array();
foreach ($userList as $user) {
     $userData[] = '("'.$user['first_name'].'", "'.$user['last_name'].'")';
}
$query = 'INSERT INTO users (first_name,last_name) VALUES'.implode(',',$userData);
mysql_query($query);

我的问题是... 1. 让你的查询远离循环有多重要,它总是可以避免的吗? 2. 你怎么能用同样的逻辑来实现一个 SELECT 语句。

即假设我有这个查询。

$index=0;
while ($index < count($id)) {
     $result[] = mysql_query("SELECT * FROM tblInfo WHERE site_id = '".$id[$index]."' ");
     $index++;
}

如何在循环之外执行这个 SELECT 语句?我有大量比这复杂得多的 SELECT 语句。因此,如果认为有必要,我想让这些查询脱离循环。如果有人同意谷歌,您能否发布一些示例代码。

任何回复将不胜感激。

【问题讨论】:

  • 第一个例子没有意义。我怀疑您的“脚本”必须不断地进行批量插入。而对于一次性操作来说,这样的循环并不重要。至于选择 - 只需学习 SQL
  • SQL 是基于 SET 的,而不是过程的。

标签: php mysql performance optimization google-code


【解决方案1】:

您可以使用带有 ID 列表的 MySQL IN 运算符。

SELECT * FROM table WHERE id IN (1,4,6,8,5,6)

它甚至可以处理包含数千个 ID 的非常长的列表(当然比数千个 SELECTs 更好)。但在这种情况下,您还应该考虑应用程序的设计。如果您需要在每次页面加载时使用带有数千个 ID 的 IN,那么您的设计就大错特错了。

INSERTs 也可以压缩成一个查询,见documentation

通常,循环中的大多数查询通常可以是rewritten as subqueries。但是在这种情况下,您必须在性能和可读性/可维护性之间做出选择。子查询通常很难理解和优化/调试。

【讨论】:

    【解决方案2】:

    【讨论】:

      【解决方案3】:

      避免往返费用对您来说有多重要取决于几件事。

      首先,您要往返多少次?如果您正在制作 3 或 4,您可能会忽略该建议,如果听从它会很痛苦。

      其次,在您的设置中,往返的费用是多少?如果到数据库的往返需要 100 毫秒,那么避免这种情况比只需要 2 毫秒要严重得多。

      第三,需要进行查询的过程对时间有多敏感?如果你让用户等待,你真的应该注意这一点——用户讨厌等待!如果您使用的是在幕后运行并执行某些工作的 Ajax 进程,那么它可能就不那么重要了(尽管您可能仍然需要注意超时)。

      基本上,Google 的建议是好的,因为浪费时间就是浪费时间。但是,根据您的具体情况,浪费的时间对您、您的系统和您的用户来说可能或多或少是严重的。

      【讨论】:

      • 现在,我对数据库进行了 17 次访问。随着我们在未来几年开设更多地点,这个数字将翻倍。至于需要多少时间,我不确定。我将进行一些测试,看看它需要多长时间。我(还)没有使用 AJAX,但将来肯定有可能。浪费的时间并不那么重要,但我想以“正确”的方式做事,因为我努力学习高效的编程。
      • 但是多久一次,每个需要多长时间,延迟对您来说有多重要?这些确实是重要的问题。不过,随着您人数的增加,Google 的建议可能会对您越来越有益。
      猜你喜欢
      • 1970-01-01
      • 2012-09-18
      • 2017-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多