我正在寻找一种好的设计模式或最佳实践,以实现“要么这个查询,要么那个其他查询”的情况,同时具有最佳性能和最少开销。
demans 的业务逻辑/程序说“自 Foo 以来的所有项目”,除非返回少于三个项目,然后返回“所有项目”。 我正在重构当前的代码,并没有想出一个很好的方法来实现这个逻辑。
当前的伪代码(Drupal/PHP):
<?php
$result = db_query(
'SELECT n.uid FROM og_ancestry oga ' .
'INNER JOIN node n on n.nid = oga.nid ' .
'WHERE oga.group_nid = %d AND n.created > %d GROUP BY n.uid ' .
'ORDER BY cnt DESC LIMIT %d', $group_nid, $since, $limit);
while ($row = db_fetch_array($result)) {
$uids[] = $row['uid'];
}
if (count($uids) < 3) {
$result = db_query(
'SELECT n.uid FROM og_ancestry oga ' .
'INNER JOIN node n on n.nid = oga.nid ' .
'WHERE oga.group_nid = %d GROUP BY n.uid ' .
'ORDER BY cnt DESC LIMIT %d', $group_nid, $limit);
while ($row = db_fetch_array($result)) {
$uids[] = $row['uid'];
}
}
//...do something with the result.
?>
这段代码感觉“不对”,首先是因为 DRY:它包含相同的查询,只有一点点不同。我可以通过更智能的查询构建来改变它。
但更糟糕的是,我需要锤击数据库(查询非常繁重)才发现在超过一半的情况下,我需要丢弃结果并再次查询数据库。
您将如何处理这种情况?
最佳答案
如果,如您所说,“在超过一半的情况下,我需要丢弃结果并再次查询数据库”,那么您最好的选择可能是仅第二次运行查询然后在本地评估结果数据集,如果合适则丢弃记录。与其说是降低复杂性,倒不如说是移动复杂性的问题,但至少只需要访问一次数据库。
如果您ORDER BY n.created DESC
,过滤可以简单地查看第三条记录,如果它早于 foo,您就完成了;否则,您需要找到 foo 之前的第一条记录并丢弃它和后续记录。
关于php - 如果数据库查询 A 没有返回足够的结果,运行查询 B : how to optimize?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3531947/