【发布时间】:2013-08-29 13:33:17
【问题描述】:
我想我是来问一个你们很多人已经问过自己的问题,我想。我正在创建一个 PHP 网站,一切都运行顺利,直到我决定用一些测试数据填充我的数据库(真实数据,当应用程序开始真正使用时,它会变得更大)。大多数事情仍然可以正常工作,但一个特定(并且非常重要)的功能开始执行时间为 3 到 4 秒,其中大部分时间都花在了 MySQL 服务器上。
交易是这样的:我正在为一所学校构建一个应用程序,它需要包含每天、每个人、每个房间、每个班级的所有时间表和课程。完成了数据库的结构,创建了索引,等等……问题是,由于所有这些数据都是关系型的(并且可以分布在许多表中),因此获取它们的查询可能如下所示:
SELECT field1, field2, etc
FROM schedules AS su
LEFT JOIN schedules_lessons AS sul
ON sul.ID_SCHEDULE = su.ID
LEFT JOIN schedules_lessons_teachers AS sult
ON sult.ID_LESSON = sul.ID
LEFT JOIN users AS u
ON u.ID = sult.ID_TEACHER
LEFT JOIN schedules_periods AS sup
ON sup.ID_SCHEDULE = su.ID
LEFT JOIN schedules_periods AS sulp
ON sulp.ID_SCHEDULE = sul.ID_SCHEDULE AND sulp.period = sul.period
LEFT JOIN schools AS s
ON s.ID = su.ID_SCHOOL
LEFT JOIN schools_buildings AS sb
ON sb.ID_SCHOOL = s.ID
LEFT JOIN schools_rooms AS sr
ON sr.ID = sul.ID_ROOM
LEFT JOIN schools_classes AS sc
ON sc.ID = sul.ID_CLASS
是的,我知道有很多连接。我的问题是:我应该如何在连接数量和数量或查询之间取得最佳平衡?因为我觉得这真的可以改进,但我不知道如何实现它。
大多数表的记录数都在 200 以下,只有课程表可以有更多。最小值接近 5k,最大值可能是 30k 或更多。
【问题讨论】:
-
在不知道你的架构的情况下很难给出建议,但从你的查询中猜测出来,似乎没有什么问题。为了提高性能,您是否正确索引了所有表中的所有相关字段(示例中的所有外键)?此外,与
schedules_periods AS sulp的第二个连接似乎是多余的,只需将第一个连接更改为LEFT JOIN schedules_periods AS sup ON sup.ID_SCHEDULE = su.ID AND sup.period = sul.period。关于查询长度,您可以使用一些视图来缩短查询。规范化良好的数据库没有任何问题。 -
这样的东西是 nosql 大放异彩的地方.. 看起来很可怕。
-
@Eggplant 你好。好吧,事实是(冗余)查询是我用来进行排序工作的一个小技巧。这有点难以解释。这是因为周期是特定于日程的,这意味着它们对于每个日程都是不同的。因此,我不仅要选择与课程相对应的时段,还要选择与整个时间表相对应的时段,同时仍要在课程开始前订购课程。 :)
标签: php mysql sql performance relational-database