我们有一个内部PHP Web应用程序,它是我们用户的财务分析工具。我们处理客户'财务信息,以分析他们偿还贷款的能力。
我们已经构建了一个具有生成大量数字和比率的函数的类。我们使用它们来显示应用程序中不同页面的总数,比率等。我们有许多函数可以生成总计和许多函数,这些函数使用函数的总计来生成新的总计和比率。这是一个例子:
//Coverage Ratio
public function CoverageRatio($hma) {
return div_check(($this->NetFarmIncome($hma) + $this->NetNonFarmIncome($hma) - $this->FamilyLivingExpenses() - $this->IncomeTaxes()), ($this->InterestPortionTermDebt($hma) + $this->PrincipalPortionTermDebt($hma)));
}
//Operating Expense Ratio
public function OperatingExpenseRatio($hma) {
return div_check($this->FarmOperatingExpenses($hma), $this->GrossFarmIncome($hma));
}
//Net Nonfarm Income
public function NetNonfarmIncome($hma = null) {
$result = $this->db->query("SELECT ah.id, COALESCE(v1.h1, 0) - COALESCE(v2.h2, 0) AS h, COALESCE(v1.p1, 0) - COALESCE(v2.p2, 0) AS p, COALESCE(v1.a1, 0) - COALESCE(v2.a2, 0) AS a FROM analysis_history ah LEFT JOIN (SELECT analysis_id, ... GROUP BY analysis_id) AS v2 ON v2.analysis_id = ah.id WHERE ah.id = $this->analysisid");
$row = $result->fetch_assoc();
return $row['a'];
}
//Net Business Income
public function NetBusinessIncome($hma = null) {
$result = $this->db->query("SELECT ah.id, COALESCE(v1.h1, 0) - COALESCE(v2.h2, 0) AS h, COALESCE(v1.p1, 0) - COALESCE(v2.p2, 0) AS p, COALESCE(v1.a1, 0) - COALESCE(v2.a2, 0) AS a FROM analysis_history ah LEFT JOIN (SELECT analysis_id, ... GROUP BY analysis_id) AS v2 ON v2.analysis_id = ah.id WHERE ah.id = $this->analysisid");
$row = $result->fetch_assoc();
return $row['a'];
}
在过去一年中,已经进行了很多改变,我们不得不增加许多新的总数和比率。修改我们的应用程序以生成页面加载时间并计算执行的查询数量后,我们感到震惊。我们最大的页面生成需要0.8秒,并且有122个查询。
我们已经做了一些调整以减少查询次数,但我们只能裁掉大约10个查询。我们的平均页面有大约35个查询,我们觉得这些查询太多了。
在我们保存分析逻辑的类中,我们是否应该更改从多个函数中提取数据的函数(并对数据库进行多次调用)并让它们执行单个查询?在我的CoverageRatio示例中,其中的每个函数实际上都在查询数据库--6个单独的查询。
哪种方法可以更好地优化我们的代码?它是否很好 - 我们喜欢这种方式以防万一我们需要做出改变 - 我们只改变生成特定总数的函数。管理14个以上都使用净收入计算的函数将成为一场噩梦 - 如果我们不得不修改计算净收入的方式,我们就必须改变依赖于该值的每个函数中的每个查询。谢谢你的帮助!
答案 0 :(得分:3)
如果要从同一组表中计算多个内容,使用单个SELECT语句执行此操作会更有效,该语句在单独的列中执行所有计算,而不是为每个计算执行单独的SELECT语句。
您还可以通过使用临时表来保存多个其他查询所需的中间结果来提高性能,以避免在使用它们的每个查询中重新计算这些值。
如果您的查询涉及大量连接,请使用EXPLAIN来研究数据库如何执行这些连接,并查看是否可以添加任何索引以使连接更有效。一些精心挑选的指数可能会产生很大的不同。