У меня есть существующий SQL-запрос, который работает хорошо, но требует того, что я считаю довольно небольшим количеством времени и ресурсов для такого небольшого набора результатов. Я пытаюсь выяснить, можно ли оптимизировать следующий запрос, чтобы я был незнакомым для повышения производительности.
SELECT
a.programname, count(b.id)
FROM
groups a
LEFT JOIN
selections b ON (a.id_selection = b.id AND a.min_age = 18 AND a.max_age = 24)
LEFT JOIN
member_info c ON (b.memberid = c.memberid AND (c.status = 1 OR c.term_date > '2011-01-31'))
WHERE
a.flag = 3
GROUP BY
a.programname
ORDER BY
a.programid asc;
Здесь три таблицы:
Группы содержат список возможных вариантов выбора, которые может внести член. Член может иметь множественный выбор во всей таблице, но может иметь только один выбор для каждого имени программы и только один возрастный кронштейн. Общая программа определяется флагом, который ограничивает 400+ программ только 100 возможными миксами. Названия программ, сгруппированные вместе:
только член, член плюс супруга, член плюс ребенок, семья
Результат должен возвращать счет всех активных членов, которые имеют этот конкретный выбор, даже если результат равен 0 (т.е. не может ограничить набор результатов 3 строками только потому, что у него есть нулевой подсчет).
В этой таблице группируются элементы выбора для нескольких групп. Один член может иметь несколько идентификаторов из групп, но только один из каждого типа.
содержит информацию о каждом конкретном члене, включая их статус (1 активен), и если дата их завершения передается в случае, если они неактивны.
Мой запрос занимает почти 3/4 полной секунды, что я считаю слишком большим для этого времени информации, но, возможно, я ошибаюсь со всеми необходимыми объединениями.
Любая помощь приветствуется. В случае необходимости я могу расширить свой вопрос.
1 SIMPLE a ALL 184 Using where; Using temporary; Using filesort
1 SIMPLE b index memberid_id 7 3845 Using index
1 SIMPLE c ALL 1551
Я много думал об использовании индексов в отношении этого запроса, но, как предполагают почти все источники, использование в подобном примере может на самом деле быть вредным. Лучшее резюме, которое я нашел, было:
Индексы - это нечто лишнее, что вы может включать в ваши таблицы MySQL увеличить производительность, cbut они действительно имеют некоторые недостатки. Когда вы создаете новый index MySQL строит отдельный блок информацию, которую необходимо обновить каждый раз, когда происходят изменения, внесенные в стол. Это означает, что если вы постоянно обновлять, вставлять и удаление записей в вашей таблице может оказать негативное влияние на производительность.
Таблица member_information будет расти ежедневно, группы останутся довольно постоянными, но таблица выбора может резко меняться ежедневно. Таким образом, использование индексов действительно имеет отрицательный эффект в этом случае.
Есть ли у вас индексы на присоединяемых столбцах? Это было бы очевидным первым шагом.
Кажется, никаких проблем с этим запросом не возникает. Ваши варианты
Помимо этого, в системе должно быть какое-то серьезное узкое место или миллионы строк в таблицах, которые вызывают длительное выполнение.
Как вы выполняете запрос, если вы выполняете запрос 100 раз параллельно?
Если вы часто запускаете этот запрос, попробуйте использовать параметры привязки, а не просто конкатенировать sql. Таким образом, механизм db может кэшировать план выполнения.