Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Caros,
Preciso de uma grande ajuda e não estou conseguindo avançar.
Tenho um banco de dados MySQL com 1 tabela que contem mais de 8.000.000 campos. Basicamente ela é assim (exemplo):
ID
ID_Equipamento
Valor1
Valor2
5000
10
fdas
341341
4999
9
fdas
15145
4998
8
fasfa
4351
4997
7
fdafd
415
4996
3
das
67467
4995
2
dasdasdas
7
4994
1
qgrgbsg
74
4993
9
bsgb
423527
4992
8
sgarhy
6
4991
6
bsbsgb
8461546
4990
5
rwrqrqrgaf
5
4989
4
fvafdv
87
4988
3
afvafg
85
4987
1
afvafg
85
4986
5
ag
634
4985
3
gfag
2
4984
2
fdaga
51
4983
9
gfaga
431
4982
8
gffga
245262653
4981
6
gfa
2
Onde ID é um auto incrementador na hora da inserção de um dado.
E ID_Equipamento é a referência de qual equipamento as informações são.
Estou precisando pegar os últimos valores (Valor1, Valor2) de cada ID_Equipamento (Todos os ID_Equipamentos - 1 a 10, mas somente o último cadastrado).
O último valor seria pelo último ID cadastrado daquele ID_Equipamento
Nesse caso seria:
ID
ID_Equipamento
Valor1
Valor2
5000
10
fdas
341341
4999
9
fdas
15145
4998
8
fasfa
4351
4997
7
fdafd
415
4996
3
das
67467
4995
2
dasdasdas
7
4994
1
qgrgbsg
74
4991
6
bsbsgb
8461546
4990
5
rwrqrqrgaf
5
4989
4
fvafdv
87
Já tentei utilizar o DISTINCT, porém ele só retorna uma coluna com o ID_Equipamento:
ID_Equipamento
10
9
8
7
3
2
1
6
5
4
Há alguma possibilidade de fazer o que eu quero fazer? Ou usando group by? ou MAX(ID)?
Depois que conseguir fazer no MySQL, irei passar pro PHP e assim o tempo não pode ser tão alto para a execução...
Grato!
Obrigado pela ajuda.
Mas suponho que pela quantidade de IDs (10 milhões) e pela quantidade de ID_Equipamento (300), ainda continua lento o sistema.
A primeira ideia nem consegui rodar, ficou carregando...
Obrigado mais uma vez...
Se o Id e id_equipamento possuem índices então o problema está sendo cruzar os dados com o sub select, nesse caso você pode substitui-lo por uma view materializada, que nada mais é que uma tabela auxiliar que você ira alimentar antes da consulta e/ou via triggers sempre que houver alterações na tabela.
VIEW MATERIALIZADA
CREATE TABLE ultimos_lancamentos (
id INTEGER PRIMARY KEY,
id_equipamento INTEGER NOT NULL UNIQUE,
FOREIGN KEY fk_ultimos_lancamentos_id (id) REFERENCES tabela(id) ON DELETE CASCADE,
FOREIGN KEY fk_ultimos_lancamentos_id_equipamento (id_equipamento) REFERENCES equipamentos(id) ON DELETE CASCADE
);
E caso raramente vá consultá-la pode populá-la antes de cada consulta.
TRUNCATE ultimos_lancamentos;
INSERT INTO ultimos_lancamentos(id, id_equipamento)
SELECT MAX(id), id_equipamento FROM tabela GROUP BY id_equipamento;
Se for consultá-la constantemente pode atualizá-la imediatamente criando um triggers ao inserir e atualizar(caso o id do equipamento possa ser alterado posteriormente) a chave estrangeira já cuida da remoção quando houver.
CREATE TRIGGER atualizar_ultimos_lancamentos_insert AFTER INSERT ON tabela
FOR EACH ROW REPLACE ultimos_lancamentos(id, id_equipamento) VALUES(NEW.id, NEW.id_equipamento);
CREATE TRIGGER atualizar_ultimos_lancamentos_update AFTER UPDATE ON tabela
FOR EACH ROW REPLACE ultimos_lancamentos(id, id_equipamento) VALUES(NEW.id, NEW.id_equipamento);
Independente do modo escolhido sua consulta ficaria assim:
SELECT
tabela.id,
tabela.id_equipamento,
tabela.valor1,
tabela.valor2
Sim é possível, seguem alguns meios de se fazer isso, sendo o primeiro preferível aos outros:
FROM tabela INNER JOIN ON ultimo_registro_por_equipamento.id = tabela.id ORDER BY tabela.id DESC/Também é possível alcançar o mesmo resultado com as seguintes consultas porem a menos que o banco consiga otimiza-las elas tendem a ter um desempenho inferior./
FROM tabela WHERE ORDER BY tabela.id DESC/ou/
FROM tabela AS t1 WHERE ORDER BY t1.id DESCO que elas fazem é consultar os maiores IDs da tabela por equipamento e depois buscar os dados com base neles, as consultas alternativas tendem a ser mais lentas pois a subquery será executada para cada registro no banco enquanto com o join ela será executada somente uma vez.
Você pode realizar testes em http://sqlfiddle.com/#!9/01f85c/11.