Повышение производительности в этом запросе
-
13-10-2019 - |
Вопрос
У меня есть 3 таблицы с пользовательскими входами:
SIS_LOGIN => Администраторы TB_RB_ESTRUTURA => Координаторы TB_USUARIO => Клиенты
Я создал представление, чтобы объединить всех этих пользователей, разделяя их на уровне, следующим образом:
create view `login_names` as select `n1`.`cod_login` as `id`, '1' as `level`, `n1`.`nom_user` as `name` from `dados`.`sis_login` `n1`
union all
select `n2`.`id` as `id`, '2' as `level`, `n2`.`nom_funcionario` as `name` from `tb_rb_estrutura` `n2`
union all
select `n3`.`cod_usuario` as `id`, '3' as `level`, `n3`.`dsc_nome` as `name` from `tb_usuario` `n3`;
Таким образом, может возникнуть до трех идентификаторов, повторяющихся для разных пользователей, поэтому я разделен на уровне. Эта точка зрения просто для того, чтобы вернуть мне имя пользователя, в соответствии с его идентификатором и уровнем. Учитывая, что у него есть около 500 000 зарегистрированных пользователей, эта точка зрения занимает около 1 секунды для загрузки. Слишком много времени, но становится очень маленьким, когда мне нужно вернуть последние сообщения на форуме моего сайта.
Таблицы форумов возвращают идентификатор пользователя и уровень, а затем ищите имя в этом представлении. Я зарегистрировал 18 форумов. Когда я запускаю запрос, для каждого форума требуется один секунду = 18 секунд. МОЙ БОГ. Эта страница загружается каждый раз, когда кто -то входит в мой сайт.
Это мой запрос:
select `x`.`forum_id`, `x`.`topic_id`, `l`.`nome`
from (
select `t`.`forum_id`, `t`.`topic_id`, `t`.`data`, `t`.`user_id`, `t`.`user_level`
from `tb_forum_topics` `t`
union all
select `a`.`forum_id`, `a`.`topic_id`, `a`.`data`, `a`.`user_id`, `a`.`user_level`
from `tb_forum_answers` `a` ) `x`
left outer join `login_names` `l`
on `l`.`id` = `x`.`user_id` and `l`.`level` = `x`.`user_level`
group by `x`.`forum_id` asc
Используя объяснить:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
1 PRIMARY <derived4> ALL NULL NULL NULL NULL 530415
4 DERIVED n1 ALL NULL NULL NULL NULL 114
5 UNION n2 ALL NULL NULL NULL NULL 2
6 UNION n3 ALL NULL NULL NULL NULL 530299
Null Union
2 получено все NULL NULL NULL 3
3 Союз r Весь нулевой нулевой нуль 3
Null Union
Кто -нибудь может помочь мне или дать предложение?
Решение
Делать то, что вы хотите:
Сделать запрос where name = 'whatever'
.
Это вернется к вам только в ряд, который вы хотите. Возвращение всех рядов станет очень быстро очень быстро, поскольку количество пользователей увеличивается. И ты делаешь это 3 раза.
Убедитесь, что это имя проиндексировано, чтобы сделать его очень быстрым.
В функции, которая вызывает это, кэшируйте любое имя, которое вы уже запросили в хэш. Если он не установлен, сделайте запрос, поместите результат в хэш. Если это установлено, верните значение.
Более подробная информация о том, как это называется очень полезно.
Я бы на самом деле порекомендовал другую структуру таблицы:
Таблица 1: Пользователи
Userid, имя
Таблица 2: Разрешения
ID, UserId, уровень
Надеюсь это поможет.