多个WHERE子查询性能

问题描述

SELECT中执行多个子查询(准确地说是8个)时,我担心性能。经过测试,大约需要 5秒才能找到结果。

鉴于我有一个包含3个表的数据库combinationsgroupssubjects

group_1group_2group_3group_4引用了id中的subjectssubject_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次。 将数据重组为另一种结构将是更好的选择。