2011-05-10 143 views
2

我正在学习SQL。为了提高我的技能,我在Coderloop.com上发现了一个SQL难题。 (伟大的网站编程难题,顺便说一句)。我目前通过这个难题的工作:查找SQL查询瓶颈

http://www.coderloop.com/puzzles/university

我非常接近的解决方案。我只需要优化我的代码。这个难题要求您设计一个课程目录数据库,以及诸如“添加学生到课程”或“获取课程详细信息”等疑问。我有,我认为,是一个工作解决方案。我用我自己的数据测试过它,它似乎表现良好。但Coderloop使用数千个查询来压力测试我的数据库模式和查询。不幸的是,我的解决方案因大约4分钟左右的超时而失败。我已经检查了我的模式和查询,我找不到瓶颈。任何关于如何重新设计我的数据库或查询以加快速度的想法?

注:

  • 执行MySQL服务器
  • 上的小号是由Coderloop机器人通过测试数据的参数?看到这个page的最底部。

我Soultion

设置数据库

CREATE TABLE students (
    sid int NOT NULL, 
    name varchar(255), 
    surname varchar(255), 
    email varchar(255), 
    faculty varchar(255), 
    matriculation int, 
    PRIMARY KEY (sid) 
    ); 

CREATE INDEX stu_index ON students (sid); 
CREATE TABLE professors (
    pid int NOT NULL, 
    name varchar(255), 
    surname varchar(255), 
    email varchar(255), 
    faculty varchar(255), 
    telephone varchar(255), 
    PRIMARY KEY (pid) 
); 
CREATE INDEX pro_index ON professors (pid); 
CREATE TABLE courses (
    course_name varchar(255) NOT NULL, 
    pid int, 
    credits int, 
    subject varchar(255), 
    PRIMARY KEY (course_name) 
); 
CREATE INDEX cou_index ON courses (course_name);  
CREATE TABLE enrollment (
    course_name varchar(255), 
    sid int 
); 

添加新教授

INSERT INTO professors (name, surname, email, faculty, telephone, pid) VALUES (?, ?, ?, ?, ?, ?); 

添加一个新的学生

INSERT INTO students (name, surname, email, faculty, matriculation, sid) VALUES (?, ?, ?, ?, ?, ?); 

添加新课程

INSERT INTO courses (course_name, subject, credits) VALUES (?, ?, ?); 

添加现有教授到现有的课程

(这个疯狂的语法是相匹配的顺序的参数传递给了?S)

Update courses Set pid = Case When course_name = ? Then ? Else pid End; 

现有的学生加入到现有的课程的学生

INSERT INTO enrollment (course_name, sid) VALUES (?, ?); 

获取列表参加课程

SELECT name, surname FROM students JOIN enrollment ON students.sid=enrollment.sid WHERE course_name=?; 

获取教授拥有一门课程

SELECT name, surname, professors.pid FROM professors JOIN courses ON professors.pid=courses.pid WHERE course_name=?; 

获取过程的细节

SELECT subject, credits FROM courses WHERE course_name=?; 

获取教授细节

SELECT name, surname, email, faculty FROM professors WHERE pid=?; 

获取学生详细介绍

SELECT name, surname, email, faculty, matriculation FROM students WHERE sid=?; 

从课件

DELETE FROM enrollment WHERE sid=? AND course_name=?; 

在一门课程中删除学生更换教授

UPDATE courses SET pid=? WHERE course_name=?; 
+0

没有索引或主键?如果有足够的数据放入系统,这可能会导致问题... – ircmaxell 2011-05-10 23:59:27

+0

我认为您可能需要重新考虑“将现有教授添加到现有课程”部分。该网站表示参数是'课程名称'和'ssn',所以查询应该可能由SSN查找教授,然后从中更新课程。 – William 2011-05-11 01:06:15

回答

1

添加索引在主键和外键的字段。这会有所帮助。

此外,还要确保你有参与WHERE和ORDER BY子句(除了FK域)

最终字段的索引:你可能会需要将它缩小到具体的查询是其中那些表现缓慢,所以你可以集中精力在那里。

+0

我添加了主键和索引,但仍然失败。 (请参阅上面的编辑) – ron 2011-05-11 00:36:31

+0

您可以使用查询分析器分离哪些查询始终在咀嚼吗?这至少可以帮助你缩小问题范围。 – JohnFx 2011-05-11 01:30:07

+0

不幸的是,我无法访问压力测试的输出,因此我无法缩小查询范围。我试过运行一些单个查询,但是它们都在0.0005秒内返回。 – ron 2011-05-11 02:26:25

0

认为你需要

CREATE INDEX enr_coursename ON enrollment(course_name); 
CREATE INDEX co_pid ON courses(pid);