数据库索引在这种情况下会有帮助吗?

Will database indexes help in this context?

我有一个中小型 MySQL 数据库,我不经常 update/insert,但经常 select。最近,我在最常显示的页面之一中添加了一个相当大的 EXISTS 子句,它确实减慢了一切 - 查询需要二十多秒才能 运行!

这是一个参加夏令营的人的数据库。我有 table sct_persons 中的人员、sct_camps 中的营地以及 sct_participants 中的参与者。

这是(也许不足为奇)耗时 SQL:

SELECT DISTINCT
    sct_persons.id AS personid,
    sct_persons.name AS name,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=471 ) AS camp471,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=477 ) AS camp477,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=502 ) AS camp502,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=527 ) AS camp527,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=543 ) AS camp543,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=546 ) AS camp546,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=554 ) AS camp554,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=584 ) AS camp584,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=606 ) AS camp606,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=620 ) AS camp620,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=621 ) AS camp621,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=622 ) AS camp622,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=677 ) AS camp677,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=679 ) AS camp679,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=628 ) AS camp628,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=689 ) AS camp689,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=680 ) AS camp680,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=682 ) AS camp682,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=693 ) AS camp693,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=695 ) AS camp695,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=683 ) AS camp683,
    EXISTS( SELECT id FROM sct_participants WHERE person=personid AND camp=684 ) AS camp684
FROM sct_persons
JOIN sct_participants
ON sct_persons.id=sct_participants.person
WHERE camp=695
AND sct_participants.student=1
ORDER BY name;

我知道这看起来很奇怪;它所做的是首先确定其他哪些营地(如果有的话)任何营地参与者参加过,并创建一个 table,其中包含他们以前参加或未参加过的零和一个。

有人告诉我可以通过使用索引来加快速度,但我发现所有可用的索引介绍都非常抽象且难以理解,我不确定在这种情况下是否会有帮助。

如有任何帮助或意见,我们将不胜感激!

如果尚未完成,请在以下位置创建索引:

sct_persons.id 

sct_participants.person, sct_participants.camp, sct_participants.student 

这肯定会加快速度,因为这些是连接中使用的字段和 where 条件中使用的字段。当它们通常在同一连接或条件中一起使用时,您可以创建一个组合更多它们的索引。

首先构建非透视查询。然后将其用作派生的 table 来调整结果。这看起来对第一步正确吗?

SELECT
        s.id AS personid,
        s.name,
        t.id,
        t.camp
    FROM sct_persons AS s
    JOIN sct_participants AS t  ON s.id = t.person
    WHERE s.camp = 695
    AND t.student = 1
    ORDER BY s.name;

我删除了不需要的 DISTINCT?并迷失了哪些列在哪些 table 中。而且我不明白为什么有两个引用 sct_participants;可以只用一个吗?你提到了 3 table,但你的查询只显示了 2??

请用散文形式解释目标的目的。