Помогут ли индексы базы данных в этом контексте? - PullRequest
0 голосов
/ 05 апреля 2019

У меня есть база данных MySQL небольшого и среднего размера, где я не очень часто обновляю / вставляю, а выбираю довольно часто.Недавно я добавил довольно большое предложение EXISTS на одну из наиболее часто показанных страниц, и оно действительно все замедляет - запрос выполняется более двадцати секунд!

Это база данных лиц, которые участвуютв лагерях.У меня есть люди в таблице 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;

Я знаю этовыглядит странно;он сначала определяет, в каких других лагерях, если таковые имеются, участвовал кто-либо из участников лагеря, и создает таблицу с нулями, а также таблицы, в которых они участвовали или не участвовали ранее.

I 'Мне сказали, что я могу ускорить его с помощью индексов, но я нахожу все доступные вступления для индексов очень абстрактными и трудными для понимания, и я не уверен, что это будет полезно в этом случае.

Любойпомощь или комментарии будут оценены!

Ответы [ 2 ]

2 голосов
/ 05 апреля 2019

Если это еще не сделано, создайте индексы для:

sct_persons.id 

и

sct_participants.person, sct_participants.camp, sct_participants.student 

Это наверняка ускорится, поскольку эти поля используются в соединениях и используются в тех условиях, где,Вы можете создать индекс, объединяющий их больше, если они обычно используются вместе в одном соединении или в одном условии.

0 голосов
/ 22 апреля 2019

Начните с построения неповоротного запроса. Затем используйте это в качестве производной таблицы для поворота результатов. Это выглядит правильно для первого шага?

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

Пожалуйста, объясните в прозе, что цель пытается сделать.

...