2013-08-29 40 views
0

我在这里要问一个问题,你们中许多人已经问自己,我想。我正在创建一个PHP网站,并且一切都一直顺利运行,直到我决定用一些测试数据(实际数据,当应用程序开始真正使用时,将会变得更大)填充我的数据库为止。大多数情况仍然可以正常工作,但是一个特别的(并且非常重要的)功能开始执行时间为三到四秒,而且大部分时间都花在了MySQL服务器上。许多(很多)SQL连接VS多个查询

这里的交易:我建立一个应用程序的一所学校,它需要将所有每天的时间表和教训,每一个人,每一个房间,每一个类。数据库的结构做了,创建索引,等等的问题是,由于所有这些数据是关系(并且可以跨多台传播)一个查询来获取他们都可能是这样的:

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或更多。

+0

不知道你的模式是不容易给意见,但是从你的查询猜测它,似乎有什么不对劲的地方。为了提高性能,您是否已在所有表格中正确编制了所有相关字段(示例中的所有外键)的索引?此外,第二次加入'schedules_periods AS sulp'似乎是多余的,只需将第一次加入更改为'LEFT JOIN schedules_periods AS sup sup.ID_SCHEDULE = su.ID AND sup.period = sul.period'。关于查询长度,您可以使用一些视图来缩短查询时间。规范化的数据库没有错。 – Eggplant

+0

像这样的东西是nosql闪耀的地方..那是可怕的看看。 – sircapsalot

+0

@Eggplant嗨。那么,事实是(冗余)查询是我用来完成排序工作的一个小技巧。这有点难以解释。这是因为这些时间段是特定于时间表的,这意味着它们对于每个时间表都是不同的。因此,我不仅要选择与课程相对应的时间段,还要选择与整个时间表相对应的时间段,而只是在课程开始时排序。 :) –

回答

0

如果需要此信息和表适当的索引,那么你的连接查询应该是一个非常合理的方式来提取数据。查询前可以通过添加explain来查看索引是否正在使用。

当你说“大部分的[的]时间花费在MySQL服务器”,你考虑到返回数千行需要时间?您可以尝试执行相同的查询,但用select count(*)替换select . . .以查看底层查询性能。另一种方法是将order by <something> limit 1添加到现有查询 - order by必须在返回结果之前完全处理该查询。

最后,如果这只是开始成为一个问题,是什么,因为它的工作,你希望它的方式改变了吗?

+0

嗨,谢谢你的答案。那么,这是因为我将一些真实的数据插入数据库(创建那些4k +行)。另外,我已经为每个表检查了phpMyAdmin,并且检查了索引,并且它们都是为这些字段创建的。另外,当我说查询时间时,我实际上只是在获取结果之前测量查询函数所花费的时间。此外,遵循您使用count(*)的建议将执行时间降低到1.5秒。 –

0

我不是一个数据库专家,但也许是有意义的只查询从您目前需要在你的应用程序或网页数据库中的信息。 这应该可以在相当短的时间内,我猜。 其余的可以在实际需要时从数据库中查询。

请注意,数据库服务器是建立一个大表在内存中的所有连接进行合并。如果您的服务器内存太少,则可能难以构建此表。 (虽然可能大概不会在您的方案的情况下...)

0

尽可能你应该让数据库处理加入,避免超过必要让更多的查询。理论上这应该是最佳的。你的查询似乎很好提供所有的连接字段索引。 规定的卷不是什么壮观的,响应时间应该是罚款(再次提供所有索引创建)。 请记住,您应该很少有如果有查询返回许多记录(当然是一个例外报告) - 在应用程序中,你应该用分页来控制它。

+0

嗨,谢谢你的答案。事实上,实际上没有办法减少我向数据库查询的内容,因为我只查询属于用户请求的计划的课程。它最终可能会最多返回30个课程。 :) –

+0

嗨,根据您的信息:30条记录返回和执行时间> 1秒我会说可能有索引缺失,或者您的数据库非常缓慢。你应该检查执行计划。 – user2497369