简体   繁体   English

处理一个类中多个查询的最佳方法?

[英]Best way to handle multiple queries in a class?

We have an in-house PHP web application that is a financial analysis tool for our users. 我们有一个内部PHP Web应用程序,它是为用户提供的财务分析工具。 We process customers' financial information to analyze their ability to pay back a loan. 我们处理客户的财务信息,以分析其偿还贷款的能力。

We have built a class that has functions to generate lots of numbers and ratios. 我们建立了一个类,该类具有生成大量数字和比率的功能。 We use these to display totals, ratios, etc. throughout the different pages in the application. 我们使用这些来显示应用程序中不同页面的总计,比率等。 We have lots of functions that generate totals and lots of functions that use the totals from functions to generate new totals and ratios. 我们有很多生成合计的函数,还有很多使用函数合计来生成新的合计和比率的函数。 Here's an example: 这是一个例子:

//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'];
}

Over the last year, lots of changes have been made and we've had to add lots of new totals and ratios. 在过去的一年中,进行了许多更改,我们不得不添加许多新的总计和比率。 After modifying our application to generate the page load time and count the number of queries that are executed, we were shocked. 修改应用程序以生成页面加载时间并计算已执行查询的数量后,我们感到震惊。 Our largest page takes .8 seconds to generate and has 122 queries. 我们最大的页面需要0.8秒钟来生成,并具有122个查询。

We've made some adjustments to decrease the number of queries, but we were only able to shave off about 10 queries total. 我们进行了一些调整以减少查询数量,但总共只能减少大约10个查询。 Our average page has about 35 queries which we feel is just too much. 我们的平均页面上有大约35个查询,我们认为这太多了。

In our class which holds the analysis logic, should we change the functions that pull data from multiple functions (and make several calls to the database) and just have them perform the single query? 在具有分析逻辑的类中,我们是否应该更改从多个函数中提取数据的函数(并多次调用数据库),然后让它们执行单个查询? In my CoverageRatio example about, every function in it actually queries the database--6 separate queries. 在我的CoverageRatio示例中,其中的每个函数实际上都查询数据库-6单独的查询。

Which is the best way to better optimize our code? 哪种是更好地优化代码的最佳方法? Is it fine the way it is--we like it this way just in case we need to make a change--we only change the function that generates that particular total. 情况是否很好-我们喜欢这样,以防万一需要进行更改-我们只更改生成特定总数的函数。 It would become a nightmare to have to manage 14+ functions that all use a net income calculation--if we ever had to modify how net income is calculated, we would have to change every query in every function that relies on that value. 必须管理14个以上全部使用净收入计算的功能将变成噩梦-如果我们不得不修改净收入的计算方式,我们将不得不更改依赖该值的每个功能中的每个查询。 Thanks for your help! 谢谢你的帮助!

If you're computing multiple things from the same set of tables, it'd be more efficient to do it with a single SELECT statement that does all the computations in separate columns, rather than a separate SELECT statement for each computation. 如果您要从同一组表中计算多个事物,那么使用单个SELECT语句(将所有计算都放在单独的列中)而不是每个计算使用单独的SELECT语句来进行处理会更有效。

You might also be able to improve performance by using temporary tables to hold intermediate results that are needed by multiple other queries, to avoid recomputing those values in each query that uses them. 您还可以通过使用临时表保存多个其他查询所需的中间结果来提高性能,从而避免在使用它们的每个查询中重新计算这些值。

If your queries involve a lot of joins, use EXPLAIN to study how the database is performing those joins, and see if there are any indexes you could add to make the joins more efficient. 如果查询涉及大量联接,请使用EXPLAIN研究数据库如何执行这些联接,并查看是否可以添加任何索引以使联接更有效。 A few well-chosen indexes may make a big difference. 一些精选的索引可能会有很大的不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM