Migliorare le prestazioni in questa query
-
13-10-2019 - |
Domanda
Ho 3 tabelle con gli accessi degli utenti:
sis_login => amministratori tb_rb_estrutura => coordinatori tb_usuario => i clienti
Ho creato allo scopo di riunire tutti questi utenti separandoli dai livelli, nel seguente modo:
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`;
Quindi, può verificarsi fino a tre ID ripetuti per diversi utenti, che è il motivo per cui mi sono separata da livelli. Questo punto di vista è solo per il nome utente ritorno me, secondo il suo id e di livello. considerando che ha circa 500.000 utenti registrati, questo punto di vista è di circa 1 secondo per il carico. troppo tempo, ma è diventa molto piccola quando ho bisogno di tornare gli ultimi messaggi sul forum del mio sito.
Le tabelle dei forum di restituire l'ID utente e il livello, quindi cercare un nome in questa vista. Mi sono registrato 18 forum. Quando eseguo la query, si vuole un secondo per ogni forum = 18 secondi. OH MIO DIO. Questa pagina viene caricata ogni volta che qualcuno entra nel mio sito web.
Questa è la mia domanda:
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
L'UTILIZZO SPIEGARE:
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 ALL RISULTATO NULL NULL NULL NULL NULL
2 DERIVATI t ALL NULL NULL NULL NULL 3
3 UNION ALL r NULL NULL NULL NULL 3
NULL UNION ALL RISULTATO NULL NULL NULL NULL NULL
Qualcuno mi può aiutare o dare un suggerimento?
Soluzione
Per fare ciò che si vuole:
Do un where name = 'whatever'
query.
Questo tornerà a voi solo la riga che si desidera. Tornando tutte le righe otterrà molto lento molto rapidamente come il numero di utenti aumenta. E si sta facendo per 3 volte.
Assicurarsi che il nome è indicizzato per renderlo molto veloce.
In una funzione che chiama questo, memorizza nella cache qualsiasi nome tu abbia già richiesto in un hash. Se non è impostata, fare la query, mettere il risultato nel hash. Se è impostato, restituire il valore.
Maggiori informazioni su come questo viene chiamata sarebbe molto utile.
vorrei davvero raccomandare una struttura di tabella diversa:
Tabella 1: gli utenti
UserId, Nome
Tabella 2: Permessi
id, UserId, Livello
Spero che questo aiuti.