问题描述
在SELECT
中执行多个子查询(准确地说是8个)时,我担心性能。经过测试,大约需要 5秒才能找到结果。
鉴于我有一个包含3个表的数据库:combinations
,groups
和subjects
。
group_1
,group_2
,group_3
和group_4
引用了id
中的subjects
。subject_id
引用了id
中的groups
。
组合:
| id | group_1 | group_2 | group_3 | group_4 |
|----|---------|---------|---------|---------|
| 1 | 6 | 4 | 6 | 9 |
| 2 | 3 | 16 | 10 | 5 |
| .. | .. | .. | .. | .. |
组:
| id | subject_id | name | max |
|----|------------|------|-----|
| 1 | 2 | 101 | 15 |
| 2 | 2 | 102 | 17 |
| .. | .. | .. | .. |
主题:
| id | name |
|----|-----------|
| 1 | "Science" |
| 2 | "Math" |
| .. | .. |
鉴于我知道科目(即数学,科学,体育和艺术)和小组(即101, 102、104、101)。
id
有什么方法可以优化性能?我曾想尝试使用combinations
,但不知道如何构造查询。
解决方法
从您提供的内容来看,这是我可能会使用JOINS编写的替代方法,但不能保证您提供的数据样本均如此。
SELECT
c.id
FROM
combinations c
JOIN Groups MathGrp
on c.Group_1 = MathGrp.ID
AND MathGrp.name = 101
join Subjects MathSub
on MathGrp.subject_id = MathSub.ID
AND MathSub.name = 'Math'
JOIN Groups SciGrp
on c.Group_2 = SciGrp.ID
AND SciGrp.name = 102
join Subjects SciSub
on SciGrp.subject_id = SciSub.ID
AND SciSub.name = 'Science'
JOIN Groups PEGrp
on c.Group_3 = PEGrp.ID
AND PEGrp.name = 104
join Subjects PESub
on PEGrp.subject_id = PESub.ID
AND PESub.name = 'P.E.'
JOIN Groups ArtGrp
on c.Group_4 = ArtGrp.ID
AND ArtGrp.name = 101
join Subjects ArtSub
on ArtGrp.subject_id = ArtSub.ID
AND ArtSub.name = 'Art'
但是,我认为这对您的例子来说更有意义。它需要组合中的所有内容,并加入相应的组。从该组中加入其主题。无论Math处于第一个还是最后一个位置,返回结果都将显示组名和主题名。
SELECT
c.id,Grp1.Name as Group1Name,Sub1.Name as Subject1Name,Grp2.Name as Group2Name,Sub2.Name as Subject2Name,Grp3.Name as Group3Name,Sub3.Name as Subject3Name,Grp4.Name as Group4Name,Sub4.Name as Subject4Name
FROM
combinations c
JOIN Groups Grp1
on c.Group_1 = Grp1.ID
join Subjects Sub1
on Grp1.subject_id = Sub1.ID
JOIN Groups Grp2
on c.Group_2 = Grp2.ID
join Subjects Sub2
on Grp2.subject_id = Sub2.ID
JOIN Groups Grp3
on c.Group_3 = Grp3.ID
join Subjects Sub3
on Grp3.subject_id = Sub3.ID
JOIN Groups Grp4
on c.Group_4 = Grp4.ID
join Subjects Sub4
on Grp4.subject_id = Sub4.ID
,
如果我正确理解了您的表和数据,则您的子查询正在测试两次相同的事物(名称= 101和名称='Math')。第一步,您可以将子查询替换为例如
SELECT id
FROM groups AS g
INNER JOIN subjects AS s
ON g.subject_id = s.id
WHERE name = 'Math'
但是,这可能不会提高性能。性能的主要问题是,您仍然需要将表组合与至少一个表(组)连接4次。 将数据重组为另一种结构将是更好的选择。