php - 使用类时查询速度慢

标签 php mysql performance pdo

这是我的 View (show.php),其中有类(class)(每门类(class)有 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>

这是 Controller (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');
    }
}
?>

还有 course_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),我都有一系列类(class))

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;

}

问题是,当我调用 Controller (方法显示)时,我需要几乎 10 秒的时间才能完成所有类(class)以及每个类(class)的类(class)。太慢了。 Workbench中查询不慢,而且类(class)有700门,所以不多。

最佳答案

问题是:您有 700 门类(class) - 每门类(class)都运行 $lezioni=$mm->getLessons($mm->cou_id);,其中执行 SQL 查询。 因此,如果获取类(class)的查询在 15 毫秒内执行(可以认为很快),那么其中 700 个查询将花费大约 10 秒。

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

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;
    }

    // ...
}

在你的 Controller 中:

$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 开头

关于php - 使用类时查询速度慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44332009/

相关文章:

php - Laravel 5.1 Ajax 代码 500

php - 在表中输入高级 SQL 查询 - 不是唯一的表别名 mysql

php - mysql选择两个表并使用 "or"变得非常慢

mysql - 在 mysql 中,我可以有一个由自动增量和另一个字段组成的复合主键吗?另外,请批评我的 "mysql partitioning"逻辑

ios - 在 Objective C 中禁用键值观察

mysql - 对 5.8 MB 数据库进行 3 秒长查询

php - mysql查询用like连接两个表

PHP 导入失败

mysql - 在带有 LIKE 的 CASE 语句中使用 GROUP_CONCAT 列别名

php - 如何为 mysql in() 进行类型转换