php - MySQL 性能命中同时访问表

标签 php mysql

以下代码是我真实代码的模型。当调用 myFunction 时,我的性能受到很大影响。 myTable 不超过几百行,但调用 myFunction 会增加大约 10 秒的执行时间。在已经访问该表的循环中尝试访问该表的一行是否存在固有错误?

<select>
<?php
  $stmt = SQLout ("SELECT ID,Title FROM myTable WHERE LEFT(Title,2) = ? ORDER BY Title DESC",
                   array ('s', $co), array (&$id, &$co_title));
  while ($stmt->fetch()) {
    if (myFunction($id))  // skip this function call and save 10 seconds
      echo '<option value="' . $co_title . '">' . $co_title . '</option>';
  }
  $stmt->close();


function myFunction ($id) {
  $stmt = SQLout ("SELECT Info FROM myTable WHERE ID = ?",
                   array ('i', $id), array (&$info));
  if ($stmt->fetch()) {
    $stmt->close();
    if ($info == $something)
      return true;
  }
  return false;
}
?>

SQLout 基本上是:

$sqli_db->prepare($query);
$stmt->bind_param;
$stmt->execute();
$stmt->bind_result;
return $stmt;

最佳答案

您所做的有时称为“N+1 查询”问题。您运行第一个(外部)查询 1 次,它返回 N 行。然后运行 ​​N 个从属查询,一个用于第一个查询返回的每一行。因此 N+1 查询。它会导致大量开销。

如果您可以在 SQL 中应用“something”条件,那么性能会好得多:

$stmt = SQLout ("SELECT ID,Title FROM myTable 
    WHERE LEFT(Title,2) = ? AND Info = ... ORDER BY Title DESC",
    array ('s', $co), array (&$id, &$co_title));

一般来说,根据与外部查询匹配的行数在循环中运行查询并不是一个好主意。如果外部查询匹配 1000000 行怎么办?这意味着循环内的一百万个查询将针对这个单个 PHP 请求访问您的数据库。

即使今天外部查询只匹配 3 行,您以这种方式构建代码的事实意味着从现在起六个月后,在某个不可预测的时间,将会有一些搜索导致巨大的开销,即使你的代码没有改变。查询数量由数据而非代码驱动。

有时需要做你正在做的事情,例如“某事”条件很复杂,不能用 SQL 表达式表示。但是您应该在所有其他情况下尝试避免这种 N+1 查询模式。

关于php - MySQL 性能命中同时访问表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15394654/

相关文章:

mysql - 搜索栏查询不起作用

php - 检查mysql中是否存在用户id

php - 在 codeigniter - google 登录回调 url 中包含特殊字符 (.) 并抛出 403 错误。怎么修?

php - MySQL 中名为 'like' 的表

mysql-workbench 未启动。加载共享库时出错 : libmysqlclient. so.18

mysql - 比较MySQL中一个表中连续的两行数据

php - Smarty 和 gettext

javascript - pdf.js 不适用于 &lt;!DOCTYPE HTML>

PHP/MySQL 日期/时间差异

php - 通过写入配置文件来构造配置语句