以下代码是我真实代码的模型。当调用 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/