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

时间:2019-04-05 09:06:20

标签: mysql indexing pivot exists

我有一个中小型的MySQL数据库,我不经常更新/插入数据库,但经常选择/更新。最近,我在显示频率最高的页面之一中添加了一个相当大的EXISTS子句,它确实使所有内容放慢了速度-查询需要20秒钟才能运行!

这是一个参加营地的人的数据库。我的桌子上有个人,sct_persons,sct_camps中的营地和sct_participant中的参与者。

这是(也许并不奇怪)耗时的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;

我知道这看起来很奇怪;它的作用是首先确定其他任何营地参与者(如果有)参加了哪些营地,并创建一个包含零的表格以及他们以前曾参加或从未参加过的地方。

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

任何帮助或评论将不胜感激!

2 个答案:

答案 0 :(得分:2)

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

sct_persons.id 

sct_participants.person, sct_participants.camp, sct_participants.student 

这肯定会加快速度,因为这些是联接中使用的字段以及在where条件中使用的字段。当它们通常在相同的联接或条件下用于手握枪时,您可以创建将它们中的更多结合在一起的索引。

答案 1 :(得分:0)

首先构建非透视查询。然后将其用作派生表以透视结果。第一步看起来正确吗?

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?并迷失在哪些表中的哪些列上。而且我不明白为什么有两个对sct_participants的引用;可以只用一个完成吗?您提到3个表,但查询仅显示2个?

请以散文形式说明目标的意图。