查找SQL查询瓶颈

时间:2011-05-10 23:55:58

标签: mysql sql

我正在学习SQL。为了提高我的技能,我在Coderloop.com上找到了一个SQL拼图。 (很棒的编程难题网站,顺便说一句)。我目前正在解决这个难题:

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

我非常接近解决方案。我只需要优化我的代码。这个难题要求您设计一个课程目录数据库,以及“将学生添加到课程”或“获取课程详细信息”等查询。我认为,这是一个有效的解决方案。我用我自己的数据进行了测试,看起来效果很好。但是Coderloop使用数千个查询来强调测试我的数据库模式和查询。不幸的是,我的解决方案因大约4分钟左右的超时而失败。我已经查看了我的架构和查询,但我找不到瓶颈。关于如何重新设计我的数据库或查询以加快速度的任何想法?

注意:

  • 在MySQL服务器上执行
  • ?s 是Coderloop bot传递的测试数据的参数。请参阅此page的最底部。

我的灵魂

设置数据库

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 (?, ?, ?);

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

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

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=?;

2 个答案:

答案 0 :(得分:1)

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

另外,请确保在WHERE和ORDER BY子句中涉及的字段上有索引(除了FK字段)

最终:您可能需要将其缩小到哪些特定查询是缓慢执行的,以便您可以集中精力在那里。

答案 1 :(得分:0)

认为你需要

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