使用class时查询速度慢

时间:2017-06-02 15:03:08

标签: php mysql performance pdo

这是我的视图(show.php),我有课程(每门课程有2-4节课)

<table width="100%" class="table table-striped table-bordered table-hover" id="dataTables-mot">
    <?php
    if (count($corsi) > 0) {
        foreach ($corsi as $mm) {

            $lezioni=$mm->getLessons($mm->cou_id);
            echo "<tr class='odd gradeX'>";
            foreach ($lezioni as $lez) {
                $data=date('d-m-Y', (float)$lez->les_ts);
                $ora=date('H:i', (float)$lez->les_ts);
                echo "
                                                <td><span style=\"display: none;\">". $lez->les_ts."</span> 
                                                    <a href='?controller=courses&action=manageMoto&id=" . $mm->cou_id . "'>" . $data . "
                                                    <div>".$ora."</div>
                                                </td>";
            }
        }
    }
    else {
        echo "<tr class='odd gradeX'><td>Nessun corso presente.</td><td></td><td><td></td><td></tr>";
    }
    ?>
</table>

这是控制器(courses.controller):

<?php
class CoursesController {

    public $tipo;
    public function show() {
        //I set the course type
        if (isset($_GET['type'])) {
            $this->tipo=$_GET['type'];
        }              
        $lezioni=getNumberLessonsByCourseType($this->getTipo());
        $corsi = Course::getCoursesbyType($this->getTipo());   
        require_once('views/courses/show.php');
    }
}
?>

和courses_model.php

<?php
include_once("connection.php");
include_once("model.php");
include_once("lessons_model.php");

Class Course extends Model{
    public $cou_id;
    public $cou_type;
    public $cou_status;
    public $cou_fbid;

    public function __construct($cou_id=null, $cou_type=null, $cou_status=null, $cou_fbid=null)
    {
        $this->cou_id = $cou_id;
        $this->cou_type = $cou_type;
        $this->cou_status = $cou_status;
        $this->cou_fbid = $cou_fbid;
    }

    public static function getCoursesbyType($type) {
        $connection= new Database();
        $selectCou = $connection->prepare('SELECT * FROM courses WHERE cou_type = :type order by cou_id desc');          
        $selectCou->bindParam(':type', $type, PDO::PARAM_INT);
        $selectCou->execute();

        $list = [];
        foreach($selectCou->fetchAll() as $corso) {
            $list[] = new Course($corso['cou_id'], $corso['cou_type'], $corso['cou_status'],$corso['cou_fbid']);
        }

        return $list;
        $connection=null;
    }

    public static function getLessons($id) {
        $connection= new Database();
        $id = intval($id);

        $selectLess = $connection->prepare('SELECT * FROM lessons WHERE les_course = :id');

        $selectLess->bindParam(':id', $id, PDO::PARAM_INT);
        $selectLess->execute();

        $list = [];
        foreach($selectLess->fetchAll() as $lezione) {
            $list[] = new Lesson($lezione['les_id'], $lezione['les_course'], $lezione['les_ts'],$lezione['les_number'],$lezione['les_instructor']);
        }
        return $list;
        $connection=null;
    }
}

我还有lesson_model.php(每个课程我都有一系列课程)

Class Lesson extends Model{

public $les_id;
public $les_course;
public $les_ts;
public $les_number;
public $les_instructor;

public function __construct($les_id=null, $les_course=null, $les_ts=null, $les_number=null, $les_instructor=null)
{
$this->les_id = $les_id;
$this->les_course = $les_course;
$this->les_ts = $les_ts;
$this->les_number = $les_number;
$this->les_instructor = $les_instructor;
}
}

getNumberLessonsByCourseType是一个简单的函数:

function getNumberLessonsByCourseType($course) {
    switch($course){
        case 'mot': $number=3; break;
        case 'mos': $number=3; break;
        case 'mop': $number=2; break;
        case 'sam': $number=2; break;
        case 'sen': $number=4; break;
    }


    return $number;

}

问题在于,当我打电话给控制器(方法显示)时,我需要将近10秒的时间来完成所有课程,并为他们每个人上课。太慢了。 工作台中的查询速度不慢,课程为700,所以不多。

1 个答案:

答案 0 :(得分:0)

问题是:您有700个课程 - 对于每个课程,您正在运行$lezioni=$mm->getLessons($mm->cou_id);执行SQL查询。 因此,如果获取课程的查询在15毫秒内执行(可以认为是快速的),那么700个查询将花费大约10秒钟。

您可以做的是在一个查询中获取所有课程的所有课程,并将它们分配给PHP课程。

Class Course extends Model{
    // ...

    public $lessons = [];

    // ...

    public static function getCoursesWithLessonsByType($type) {
        $connection = new Database();
        $selectCou = $connection->prepare('
            SELECT * 
            FROM courses
            WHERE cou_type = :type
            order by cou_id desc
        ');          
        $selectCou->bindParam(':type', $type, PDO::PARAM_INT);
        $selectCou->execute();

        $list = [];
        foreach($selectCou->fetchAll() as $corso) {
            $list[$corso['cou_id']] = new Course(
                $corso['cou_id'],
                $corso['cou_type'],
                $corso['cou_status'],
                $corso['cou_fbid']
            );
        }

        $selectLess = $connection->prepare('
            SELECT l.*
            FROM lessons l
            JOIN courses c ON c.cou_id = l.les_course
            WHERE c.cou_type = :type'
        );
        $selectLess->bindParam(':type', $type, PDO::PARAM_INT);;
        $selectLess->execute();

        foreach($selectLess->fetchAll() as $lezione) {
            $list[$lezione['les_course']]->lessons[] = new Lesson(
                $lezione['les_id'],
                $lezione['les_course'],
                $lezione['les_ts'],
                $lezione['les_number'],
                $lezione['les_instructor']
            );
        }      

        return $list;
    }

    // ...
}

在您的控制器中:

$corsi = Course::getCoursesWithLessonsByType($this->getTipo()); 

在您看来:

$lezioni = $mm->lessons;

注释

每次要运行查询时都不应打开和关闭连接。至少使用像:

这样的单身人士
$connection = Database::getInstance();

为获得最佳性能,您应该拥有以下索引:

  • courses(cou_type, cou_id)或仅courses(cou_type)如果cou_id是主键,则相同
  • lessons(les_course[, ...]) - 它可以是复合索引,但必须以les_course
  • 开头