简体   繁体   English

循环的 PHP 性能问题

[英]PHP Performance issue with loops

I use PHP to execute SQL queries and then extract timesheet data for a bunch of users.我使用 PHP 来执行 SQL 查询,然后为一群用户提取时间表数据。 Earlier it ran decently fast but has now slowed down drastically due to increase in number of Users and Tasks.早些时候它运行得相当快,但现在由于用户和任务数量的增加而大幅放缓。 I have used a number of while, for loops.我使用了许多 while 和 for 循环。 Not sure what I can optimize as calculations are iterative.不确定我可以优化什么,因为计算是迭代的。 Appreciate if someone could look at the code and suggest some options.感谢有人可以查看代码并提出一些选项。

private function processGETUSERTIMEREPORTDATA(SimpleXMLElement $xml, DBHandler $dbh) {
        $from = Utils::convertToDatetime($this->clientDateFormat, $xml->FROM);
        $to = Utils::convertToDatetime($this->clientDateFormat, $xml->TO);
        $usercode = stripslashes(html_entity_decode($xml->UNCODE));
        $this->logger->LogDebug("User List: " . $usercode);
        $userArr = json_decode($usercode, TRUE);
        $tChgMode = $xml->TASKCHGMODE;
        $tType = $xml->TASKTYPE;
        $timeSheetCategory = $xml->TIMESHEETCAT;

        $totalChgHrsArr = array();
        $totalNonChgHrsArr = array();
        $totalGenNonChgHrsArr = array();
        $totalChgDaysArr = array();
        $totalDaysALeaveArr = array();
        $totalDaysSLeaveArr = array();
        $totalDaysCLeaveArr = array();
        $totalExpensesArr = array();

        // Set timesheet category table
        if ($timeSheetCategory == "ALL") {
            $tablename = array("tblChargeHours", "tblNonChargeHours", "tblFieldDays",
                "tblNonChargeDays", "tblExpensesSheet", "tblGeneralNonChargeHours");
        } else if ($timeSheetCategory == "Chargeable Hours") {
            $tablename = array("tblChargeHours");
        } else if ($timeSheetCategory == "Non Chargeable Hours") {
            $tablename = array("tblNonChargeHours");
        } else if ($timeSheetCategory == "Chargeable Days") {
            $tablename = array("tblFieldDays");
        } else if ($timeSheetCategory == "Leaves") {
            $tablename = array("tblNonChargeDays");
        } else if ($timeSheetCategory == "Expenses") {
            $tablename = array("tblExpensesSheet");
        } else if ($timeSheetCategory == "General Non Chargeable Hours") {
            $tablename = array("tblGeneralNonChargeHours");
        }
        $arrlength = count($tablename);
        $userCount = count($userArr);

        for ($i = 0; $i < $userCount; $i++) {
            for ($x = 0; $x < $arrlength; $x++) {
                // Leaves table
                if ($tablename[$x] == "tblNonChargeDays") {

                    // Annual Leave
                    $daysSum = 0;
                    $query = "SELECT Mo, Tu, We, Th, Fr, Sa, Su from " . $tablename[$x] . " WHERE (WeekEnding BETWEEN '$from' AND '$to') AND (TaskCode='1') AND (NameCode='" . $userArr[$i] . "')";
                    $hoursRes = $dbh->executeQuery($query);

                    if ($dbh->getQueryStatus()) {
                        while ($timerow = mysqli_fetch_assoc($hoursRes)) {
                            $daysSum += ($timerow['Mo'] + $timerow['Tu'] + $timerow['We'] + $timerow['Th'] + $timerow['Fr'] + $timerow['Sa'] + $timerow['Su']);
                        }
                        $totalDaysALeaveArr[] = $daysSum;
                    } else {
                        $this->logger->LogError("Unable to generate Timesheet report data. Q : " . $query . " E : " . $dbh->getQueryMessage());
                        return ResponseGenerator::generateNegativeRepsonse($this->reqName, "Unable to generate Timesheet report data. Q : " . $query . " E : " . $dbh->getQueryMessage());
                    }

                    // Sick Leave
                    $daysSum = 0;
                    $query = "SELECT Mo, Tu, We, Th, Fr, Sa, Su from " . $tablename[$x] . " WHERE (WeekEnding BETWEEN '$from' AND '$to') AND (TaskCode='2') AND (NameCode='" . $userArr[$i] . "')";
                    $hoursRes = $dbh->executeQuery($query);

                    if ($dbh->getQueryStatus()) {
                        while ($timerow = mysqli_fetch_assoc($hoursRes)) {
                            $daysSum += ($timerow['Mo'] + $timerow['Tu'] + $timerow['We'] + $timerow['Th'] + $timerow['Fr'] + $timerow['Sa'] + $timerow['Su']);
                        }
                        $totalDaysSLeaveArr[] = $daysSum;
                    } else {
                        $this->logger->LogError("Unable to generate Timesheet report data. Q : " . $query . " E : " . $dbh->getQueryMessage());
                        return ResponseGenerator::generateNegativeRepsonse($this->reqName, "Unable to generate Timesheet report data. Q : " . $query . " E : " . $dbh->getQueryMessage());
                    }

                    // Compassionate Leave
                    $daysSum = 0;
                    $query = "SELECT Mo, Tu, We, Th, Fr, Sa, Su from " . $tablename[$x] . " WHERE (WeekEnding BETWEEN '$from' AND '$to') AND (TaskCode='3') AND (NameCode='" . $userArr[$i] . "')";
                    $hoursRes = $dbh->executeQuery($query);

                    if ($dbh->getQueryStatus()) {
                        while ($timerow = mysqli_fetch_assoc($hoursRes)) {
                            $daysSum += ($timerow['Mo'] + $timerow['Tu'] + $timerow['We'] + $timerow['Th'] + $timerow['Fr'] + $timerow['Sa'] + $timerow['Su']);
                        }
                        $totalDaysCLeaveArr[] = $daysSum;
                    } else {
                        $this->logger->LogError("Unable to generate Timesheet report data. Q : " . $query . " E : " . $dbh->getQueryMessage());
                        return ResponseGenerator::generateNegativeRepsonse($this->reqName, "Unable to generate Timesheet report data. Q : " . $query . " E : " . $dbh->getQueryMessage());
                    }

                    // GeneralNonChgHours Table 
                } else if ($tablename[$x] == "tblGeneralNonChargeHours") {

                    $hoursSum = 0;
                    $query = "SELECT Mo, Tu, We, Th, Fr, Sa, Su from " . $tablename[$x] . " WHERE (WeekEnding BETWEEN '$from' AND '$to') AND (NameCode='" . $userArr[$i] . "')";
                    $hoursRes = $dbh->executeQuery($query);

                    if ($dbh->getQueryStatus()) {
                        while ($timerow = mysqli_fetch_assoc($hoursRes)) {
                            $hoursSum += ($timerow['Mo'] + $timerow['Tu'] + $timerow['We'] + $timerow['Th'] + $timerow['Fr'] + $timerow['Sa'] + $timerow['Su']);
                        }
                        $totalGenNonChgHrsArr[] = $hoursSum;
                    } else {
                        $this->logger->LogError("Unable to generate Timesheet report data. Q : " . $query . " E : " . $dbh->getQueryMessage());
                        return ResponseGenerator::generateNegativeRepsonse($this->reqName, "Unable to generate Timesheet report data. Q : " . $query . " E : " . $dbh->getQueryMessage());
                    }
                }
            }   // end-for-tablename
        }   // end-for-usercode

        if ($tChgMode == "ALL") {
            if ($tType == "ALL") {
                // $tChgMode = ALL && $tType = ALL
                $tquery = "SELECT TCode, TType FROM tblTasks WHERE (TCreatedDate BETWEEN '$from' AND '$to')";
            } else {
                // $tChgMode = ALL && $tType = Sel
                $tquery = "SELECT TCode, TType FROM tblTasks WHERE (TCreatedDate BETWEEN '$from' AND '$to') AND (TType='" . $tType . "') ORDER BY TCode ASC";
            }
        } else {
            if ($tType == "ALL") {
                // $tChgMode = Sel && $tType = ALL
                $tquery = "SELECT TCode, TType FROM tblTasks WHERE (TCreatedDate BETWEEN '$from' AND '$to') AND (TChargeMode='" . $tChgMode . "') ORDER BY TCode ASC";
            } else {
                // $tChgMode = Sel && $tType = Sel
                $tquery = "SELECT TCode, TType FROM tblTasks WHERE (TCreatedDate BETWEEN '$from' AND '$to') AND (TChargeMode='" . $tChgMode . "') AND (TType='" . $tType . "') ORDER BY TCode ASC";
            }
        }

        $result = $dbh->executeQuery($tquery);
        $tqueryArr = array();       // Store the query results
        while ($row = mysqli_fetch_assoc($result)) {
            $tqueryArr[] = $row;
        }

        for ($i = 0; $i < $userCount; $i++) {
            $totalExpenses = 0;
            $totalChgHrs = 0;
            $totalNonChgHrs = 0;
            $totalChgDays = 0;

            foreach ($tqueryArr as $row) {
                for ($x = 0; $x < $arrlength; $x++) {
                    $tCode = $row['TCode'];

                    // Expenses Table
                    if ($tablename[$x] == "tblExpensesSheet") {
                        $query = "SELECT FinalAmount from " . $tablename[$x] . " WHERE (WeekEnding BETWEEN '$from' AND '$to') AND (TaskCode='" . $tCode . "') AND (NameCode='" . $userArr[$i] . "')";
//                        $this->logger->LogDebug($query);
                        $hoursRes = $dbh->executeQuery($query);

                        if ($dbh->getQueryStatus()) {
                            while ($exprow = mysqli_fetch_assoc($hoursRes)) {
                                $totalExpenses += $exprow['FinalAmount'];
                            }
                        } else {
                            $this->logger->LogError("Unable to generate Timesheet report data. Q : " . $query . " E : " . $dbh->getQueryMessage());
                            return ResponseGenerator::generateNegativeRepsonse($this->reqName, "Unable to generate Timesheet report data. Q : " . $query . " E : " . $dbh->getQueryMessage());
                        }

                        // Other Tables
                    } else {
                        $query = "SELECT Mo, Tu, We, Th, Fr, Sa, Su from " . $tablename[$x] . " WHERE (WeekEnding BETWEEN '$from' AND '$to') AND (TaskCode='" . $tCode . "') AND (NameCode='" . $userArr[$i] . "')";
                        $hoursRes = $dbh->executeQuery($query);

                        $totalHours = 0;

                        if ($dbh->getQueryStatus()) {
                            while ($timerow = mysqli_fetch_assoc($hoursRes)) {
                                $hoursSum = ($timerow['Mo'] + $timerow['Tu'] + $timerow['We'] + $timerow['Th'] + $timerow['Fr'] + $timerow['Sa'] + $timerow['Su']);
                                $totalHours += $hoursSum;
                            }
                            switch ($tablename[$x]) {
                                case "tblChargeHours":
                                    $totalChgHrs += $totalHours;
                                    break;
                                case "tblNonChargeHours":
                                    $totalNonChgHrs += $totalHours;
                                    break;
                                case "tblFieldDays":
                                    $totalChgDays += $totalHours;
                                    break;
                                default:
                            }
                        } else {
                            $this->logger->LogError("Unable to generate Timesheet report data. Q : " . $query . " E : " . $dbh->getQueryMessage());
                            return ResponseGenerator::generateNegativeRepsonse($this->reqName, "Unable to generate Timesheet report data. Q : " . $query . " E : " . $dbh->getQueryMessage());
                        }
                    }
                }   // end-for
            }   // end-while
            $totalExpensesArr[] = $totalExpenses;
            $totalChgHrsArr[] = $totalChgHrs;
            $totalNonChgHrsArr[] = $totalNonChgHrs;
            $totalChgDaysArr[] = $totalChgDays;
        }   // end-for-usercode

        $xmlop = new SimpleXMLElement('<RESPONSE/>');
        $xmlop->addChild("REQUESTNAME", $this->reqName);
        $xmlop->addChild("REQUESTSTATUS", "SUCCESS");
        $rowxml = $xmlop->addChild("ROW");

        $rowxml->addChild("USERCODE", json_encode($userArr));
        $rowxml->addChild("CHGHOURS", json_encode($totalChgHrsArr));
        $rowxml->addChild("NONCHGHOURS", json_encode($totalNonChgHrsArr));
        $rowxml->addChild("GENNONCHGHOURS", json_encode($totalGenNonChgHrsArr));
        $rowxml->addChild("FIELDDAYS", json_encode($totalChgDaysArr));
        $rowxml->addChild("ANNLEAVE", json_encode($totalDaysALeaveArr));
        $rowxml->addChild("SICKLEAVE", json_encode($totalDaysSLeaveArr));
        $rowxml->addChild("COMPLEAVE", json_encode($totalDaysCLeaveArr));
        $rowxml->addChild("EXPENSES", json_encode($totalExpensesArr));
        return $xmlop->asXML();
    }

Apart from the complicated code, you will probably find that you have an indexing (or lack of) issue.除了复杂的代码,您可能会发现您有索引(或缺少)问题。

Find every field that is used in any of the WHERE clauses and create an index for it.查找在任何 WHERE 子句中使用的每个字段并为其创建索引。

It's quite possible that if you have a growing database that is gradually getting slower, it could be an indexing problem.如果您的数据库不断增长并且逐渐变慢,则很可能是索引问题。

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

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