MySQL,PHP - 如何让页面更快?

时间:2014-05-18 07:40:14

标签: php mysql

我有一个由大表组成的页面,该表从不同的表中获取数据,然后计算每行的不同参数。

表本身是一个dataTable,因此它有不同的JQUERY和JS

页面非常慢。首先我有一分钟的数据上传(我看到5行然后是10行,然后是20 ......)然后我有30秒的css上传(表格看起来不同)。

有没有办法让它更快?

整个代码:

<?php
require 'init.php';
//protection
logged_out_protect_Vendor();

$data = ShowMyProjects($con);
$flag_DueDate = HaveDueDate($data); //flag is 0 if there are no projects with duedates
$guideAgent="http://dub-entas-   124.corp.ebay.com:83/tool/tagmania/guidelines/TagmaniaForAgents.docx";
$user_name=$_SESSION['username'];?>

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="css/style.css" >

<link rel="stylesheet" type="text/css" href="DataTables/jquery.dataTables.css">
<link rel="stylesheet" type="text/css" href="DataTables/shCore.css">
<link rel="stylesheet" type="text/css" href="DataTables/demo.css">

<script type="text/javascript" language="javascript" src="DataTables/jquery.js"></script>
<script type="text/javascript" language="javascript" src="DataTables/jquery.dataTables.js"></script>
<script type="text/javascript" language="javascript" src="DataTables/shCore.js"></script>
<script type="text/javascript" language="javascript" src="DataTables/demo.js"></script>

<script type="text/javascript" language="javascript" class="init">
$(document).ready(function() {
$('#example').dataTable( {
    "order": [[ 9, "desc" ]]
} );
} );
</script>

<title>Agent View</title>
<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="//cdn.datatables.net/1.10.0/js/jquery.dataTables.js"></script>
<script type="text/javascript" src="js/jquery.dataTables.columnFilter.js"></script>
    <link rel="stylesheet" type="text/css"    href="//cdn.datatables.net/1.10.0/css/jquery.dataTables.css" >
</head>


<body class="dt-example">
<div id="wrapper">
    <div id="header">
        <div id="menu">
            <img src="images/Tazlogo.gif" id="taz">
            <ul>
                <li><a href="logout.php">Log Out</a></li>
            <li> <a href="finishedWorking.php" title="By clicking on this link, you will unlock all the rows that are locked by you and can`t be answered by anyone (including you). The lock state happens when you enter the tagging page and then close it without answering the question">Unlock my rows</a></li>
            <?php echo '<li><a href ="' .  $guideAgent . '"> TagMania Guide </a></li>'; ?>
            </ul>
        </div>
    </div>
    <hr />
    <div id="page">
        <div class="welcome"> 
        <?php
        echo 'Good Day ' . $_SESSION['username'] . ', here are your tasks: ';
        ?>
        </div>
        <br>

<div class="container">
        <form method="get">
            <table id="example" class="display" cellspacing="0" width="100%"> 
            <thead>
            <tr>

            <th> Project name </th>
            <th title="general guidelines to this task"> Guidelines</th>
            <th>  Task type</th>
            <th title="Task can be new, in-process and finished. It also can have a status `archiveDM` meaning that the DM decided to archive it.">  Status</th>
            <?php
                //check that we have a duedate column
                if ($flag_DueDate==1)
                    echo '<th title="Some tasks have duedate and some don`t. Those who have a due date will be colored yellow, two days before the duedate and red after the due date. If you finish them, they will return to the regular white background"> Due Date </th>';
            ?>
            <th title="Finish date for all the tasks that were finished">  Finish Date</th>
            <th  title="The number of the rows in the task that have been tagged by you">  Tagged by you</th>
            <th  title="The number of rows that you locked. If you see here something other than 0, please click on `Unlock my rows`">  Locked by you</th>
            <th  title="The number of rows that had been tagged by all the agents">  Tagged sample</th>
            <th  title="The total number of rows in this task">   Total sample</th>
            <th  title="Link to the tagging page">  </th>
            <th  title="Here you can see a report summarizing your answers on this task"> Results</th>
            <th  title="Here you can download the task in Excel format. You can download the task on every stage - new, in process or finished">  Download </th>
            <th  title="Click on the checkboxes tasks that you don`t want to appear on the view. Then click on the archive button. Notice that they will dissapear for all the agents.">  Archive</th>
            </tr>
            </thead>

            <tfoot>
            <tr>

            <th> Project name </th>
            <th title="general guidelines to this task"> Guidelines</th>
            <th>  Task type</th>
            <th title="Task can be new, in-process and finished. It also can have a status `archiveDM` meaning that the DM decided to archive it.">  Status</th>
            <?php
                //check that we have a duedate column
                if ($flag_DueDate==1)
                    echo '<th title="Some tasks have duedate and some don`t. Those who have a due date will be colored yellow, two days before the duedate and red after the due date. If you finish them, they will return to the regular white background"> Due Date </th>';
            ?>
            <th title="Finish date for all the tasks that were finished">  Finish Date</th>
            <th  title="The number of the rows in the task that have been tagged by you">  Tagged by you</th>
            <th  title="The number of rows that you locked. If you see here something other than 0, please click on `Unlock my rows`">  Locked by you</th>
            <th  title="The number of rows that had been tagged by all the agents">  Tagged sample</th>
            <th  title="The total number of rows in this task">   Total sample</th>
            <th  title="Link to the tagging page">  </th>
            <th  title="Here you can see a report summarizing your answers on this task"> Results</th>
            <th  title="Here you can download the task in Excel format. You can download the task on every stage - new, in process or finished">  Download </th>
            <th  title="Click on the checkboxes tasks that you don`t want to appear on the view. Then click on the archive button. Notice that they will dissapear for all the agents.">  Archive</th>
            </tr>
            </tfoot>

            <tbody>
            <?php
            //i already used the data object so we need to point the pointer at the beginning of the data again
            mysqli_data_seek($data, 0);

            while ( $row = mysqli_fetch_array($data)){
                $taskId = $row['ProjectID'];
                $tasktype = $row['ProjectType'];

                include 'WhatTaskIsIt.php';

                $totalSampleQuery = "SELECT COUNT(*)as C FROM $table WHERE TaskID= $taskId";
                $totalSample = mysqli_fetch_array(mysqli_query($con, $totalSampleQuery));

                $taggedSampleQuery = "SELECT COUNT(*)as C FROM $table WHERE TaskID= $taskId AND rowstatus=2";
                $taggedSample = mysqli_fetch_array(mysqli_query($con, $taggedSampleQuery));

                $lockedByVendorQuery = "SELECT COUNT(*)as C FROM $table WHERE TaskID= $taskId AND rowstatus=1 AND Agent = '" . $user_name . "'";
                $lockedByVendor = mysqli_fetch_array(mysqli_query($con, $lockedByVendorQuery));

                // Update Project status to "In-Process" if they are New but have tagged sample
                if ($taggedSample['C']>0){
                    $ProjectStatusQuery = "SELECT ProjectStatus FROM projects WHERE ProjectID=$taskId";
                    $ProjectStatus = mysqli_fetch_array(mysqli_query($con, $ProjectStatusQuery));

                    if ($ProjectStatus['ProjectStatus'] == 1) //if the project is NEW (but have tagged rows)
                    {
                        $UpdateQuery = "UPDATE projects SET ProjectStatus=2 WHERE ProjectID=$taskId";
                        mysqli_query($con,$UpdateQuery);
                    }
                }

                //lets check what happened to the project status
                $ProjectStatusFinalQuery = "SELECT StatusName FROM projects LEFT JOIN projectstatuses ON projects.`ProjectStatus`=projectstatuses.`StatusID` WHERE ProjectID=$taskId";
                $ProjectStatusFinal = mysqli_fetch_array(mysqli_query($con, $ProjectStatusFinalQuery));

                $VendorTaggedQuery = 'SELECT COUNT(*)as C FROM ' . $table .' WHERE taskID = ' . $taskId . ' AND Agent = "' . $user_name . '" AND RowStatus=2';
                $VendorTagged = mysqli_fetch_array(mysqli_query($con, $VendorTaggedQuery));

                $linkToDownload = 'downloadFile.php';

                if ($flag_DueDate==0) {
                echo '<tr>
                        <td>' . $row['ProjectName'] . '</td>
                        <td> <a href ="' .  $row['GuidelinesURL'] . '"> Guidelines </a> </td>
                        <td>' . $row['TypeName'] . '</td>
                        <td>' . $ProjectStatusFinal['StatusName'] . '</td>
                        <td>' . showDate($row['FinishDate']) . '</td>
                        <td>' . $VendorTagged['C'] . '</td>
                        <td>' . $lockedByVendor['C'] . '</td>
                        <td>' . $taggedSample['C'] . '</td>
                        <td>' . $totalSample['C'] . ' </td>
                        <td> <a href= ' . $link . '?id=' .  $row['ProjectID'] . '&start_task=1&prevID=0>Start Working</a></td>
                        <td><a href= taskResults.php?id=' .  $row['ProjectID'] . '>Results</a> </td>
                        <td> <a href= ' . $linkToDownload . '?id=' .  $row['ProjectID'] . '>Download</a></td> 
                        <td class ="center"> <input type="checkbox" class="archive" name="archive" value=" ' . $row['ProjectID'] . '"> </td> </tr>';
                }   

                if ($flag_DueDate==1){

                if ($row['due_date'] == NULL)
                    $duedate = "";
                else
                    $duedate = $row['due_date'];

                //lets check if this duedate is late or not (but only for unfinished projects)
                if ($row['FinishDate'] ==NULL)
                    $color = Color_DueDate($duedate);
                else
                    $color ="noBackground";

                echo '<tr  class=" . ' .$color . '">
                        <td>' . $row['ProjectName'] . '</td>
                        <td> <a href ="' .  $row['GuidelinesURL'] . '"> Guidelines </a> </td>
                        <td>' . $row['TypeName'] . '</td>
                        <td>' . $ProjectStatusFinal['StatusName'] . '</td>
                        <td>' . showDate($duedate) . '</td>
                        <td>' . showDate($row['FinishDate']) . '</td>
                        <td>' . $VendorTagged['C'] . '</td>
                        <td>' . $lockedByVendor['C'] . '</td>
                        <td>' . $taggedSample['C'] . '</td>
                        <td>' . $totalSample['C'] . ' </td>
                        <td> <a href= ' . $link . '?id=' .  $row['ProjectID'] . '&start_task=1&prevID=0>Start Working</a></td>
                        <td><a href= taskResults.php?id=' .  $row['ProjectID'] . '>Results</a> </td>
                        <td> <a href= ' . $linkToDownload . '?id=' .  $row['ProjectID'] . '>Download </a></td> 
                        <td class ="center"> <input type="checkbox" class="archive" name="archive" value=" ' . $row['ProjectID'] . '"> </td> </tr>';
                }   
            }
            ?>
        </tbody>
        </table>
        <input type="button" id="archive" value="Archive" name="submit" />
        </form>
    <br><br>

    <!--imlementing archive button-->
<script>
var $varsToSend="";
$(document).ready(function() {
    $("#archive").click(function(){
    $varsToSend="";
        $(".archive:checked").each(function(){
        var $this = $(this);    
        $varsToSend=$varsToSend+$this.val()+";";
        });
        //console.log($varsToSend);

            $.ajax({
                type : 'GET',
                url : 'archiveTasksVendor.php',
                data: {
                    projectID : $varsToSend
                },
                success : function(data){
                location.reload();
                },
                error : function(XMLHttpRequest, textStatus, errorThrown) {

                }

        });
    });
});
</script>


    <?php include 'footer.html'; ?>     
</div>

对于那些想看表的人: 查询中的表是:Projects,ProjectTypes,ProjectPriorities,ProjectStatuses, 群组

TABLE `projects` (
  `ProjectID` INT(11) NOT NULL AUTO_INCREMENT,
  `DM_GROUP_ID` INT(11) NOT NULL,
  `DM_ID` INT(11) NOT NULL,
  `Vendor_GroupID` INT(11) NOT NULL,
  `Site` VARCHAR(255) NOT NULL,
  `ProjectType` INT(11) NOT NULL,
  `priority` INT(11) DEFAULT NULL,
  `ProjectName` VARCHAR(255) NOT NULL,
  `Project_Comment` VARCHAR(255) DEFAULT NULL,
  `CreationDate` DATE NOT NULL,
  `LastUpdateDate` DATE DEFAULT NULL,
  `due_date` DATE DEFAULT NULL,
  `FinishDate` DATE DEFAULT NULL,
  `ProjectStatus` INT(11) NOT NULL,
  `fileName` VARCHAR(255) DEFAULT NULL,
   PRIMARY KEY (`ProjectID`)
) ENGINE=INNODB AUTO_INCREMENT=1368 DEFAULT CHARSET=utf8

CREATE TABLE `projecttypes` (
  `TypeID` INT(11) NOT NULL AUTO_INCREMENT,
  `TypeName` VARCHAR(255) NOT NULL,
  `GuidelinesURL` VARCHAR(255) DEFAULT NULL,
  `ProjectQuestion` VARCHAR(255) DEFAULT NULL,
  `ValidReasons` VARCHAR(1000) DEFAULT NULL,
  `ValidAnswers` VARCHAR(255) NOT NULL,
  `style` VARCHAR(32) DEFAULT NULL,
  `Aspectlist` VARCHAR(255) DEFAULT NULL,
  PRIMARY KEY (`TypeID`)
 ) ENGINE=INNODB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8

CREATE TABLE `projectpriorities` (
  `PriorityID` INT(11) NOT NULL AUTO_INCREMENT,
  `PriorityName` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`PriorityID`)
) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

CREATE TABLE `projectstatuses` (
  `StatusID` INT(11) NOT NULL AUTO_INCREMENT,
  `StatusName` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`StatusID`)
) ENGINE=INNODB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8

CREATE TABLE `usergroups` (
  `GroupID` INT(11) NOT NULL AUTO_INCREMENT,
  `GroupName` VARCHAR(255) NOT NULL,
  `GroupType` VARCHAR(6) NOT NULL,
  `RelatedTo` INT(11) NOT NULL,
  PRIMARY KEY (`GroupID`)
) ENGINE=INNODB AUTO_INCREMENT=44 DEFAULT CHARSET=utf8

1 个答案:

答案 0 :(得分:3)

查询太多

您正在运行查询totalSampleQuerytaggedSampleQuerylockedByVendorQueryProjectStatusFinalQueryVendorTaggedQuery(以及可能ProjectStatusQuery和{{1 } <)> 每个行。如果从主查询中选择所有253行,则会为您提供253 + 253 + 253 + 253 + 253(可能+253 +253)额外查询。所有这些查询都会快速添加

翻转您的方法:创建一个查询,为{em>所有主表中的行生成与UpdateQuery相同的信息,运行该查询一次循环外,并使用其结果。对当前在循环中运行的所有其他totalSampleQuery查询重复此过程。更好的是,不是单独运行这些额外的查询,而是使用主查询SELECT

例如,而不是运行

JOIN

两百次,运行

SELECT COUNT(*)as C FROM $table WHERE TaskID= ?

。您将在一个查询中获得所有任务的计数。使用SELECT TaskID, COUNT(*) as C FROM $table GROUP BY TaskID 作为键将所有返回的行拉入数组,并使用主循环内该数组中的数据。

注意:您可能希望在新查询中添加某种过滤器,以仅提取与您正在显示的项目相关的数据。但是您的架构实际上并不包含名为TaskID的列,因此很难建议正确的条件。

订购和分页

优化查询后,您仍然会看到一个显示250行数据的表。显示该表需要大量的HTML,浏览器需要一段时间来渲染和设置它,并且毕竟jQuery DataTables必须将自己附加到表并按您的首选顺序对行进行排序。

  1. 考虑将页面限制为20-50行并添加分页,这将减少您正在处理的数据量以及您发送的HTML数量。
  2. 在页面加载后使用DataTables对数据进行排序,而不是在服务器上对记录进行排序 - 如果可能的话,在主查询中使用TaskID

  3. 您的代码存在更多与此特定问题无关的问题。

    1. 您在&#34; 将项目状态更新为&#34;进程中&#34;所做的更改如果他们是新的,但有标记样本&#34;应该在&#34;标记的样本&#34;行动,而不是在这里。如果您需要在其他地方显示项目状态,您要复制粘贴这个&#34;更新项目状态&#34;摘录?
    2. 与评论中提到的andrew一样,您应该重新构建代码,以便数据收集不与HTML生成交织。阅读&#34; MVC&#34;和&#34;关注点分离&#34;。
    3. 您的一个查询在ORDER BY中提及TaskID,另一个在同一$table中提及taskID。如果您的MySQL在Windows上运行,那么这两个引用相同的列,但在Linux上,表和列名称区分大小写,这意味着其中一个查询将产生错误。同样适用于$tablerowstatus更进一步。
    4. 您的错误处理在哪里?如果其中一个查询出现错误,您将继续呈现该页面,就像没有发生任何事情一样。
    5. 当您显示数据库中的数据时,您没有转义任何HTML - 如果有一个名为RowStatus的项目会怎样?