簡體   English   中英

使用類時查詢慢

[英]Slow Query when using class

這是我的視圖(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;
    }
}

我也有lessons_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,因此數量並不多。

問題是:您有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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM