MySQL Trigger Performance Degredation (to use or not to use)
DELIMITER $$
CREATE TRIGGER `increment_daily_called_count` BEFORE UPDATE ON `list`
FOR EACH ROW begin
if (NEW.called_count != OLD.called_count) then
set NEW.daily_called_count = OLD.daily_called_count(NEW.called_count-OLD.called_count);
set NEW.modify_date = OLD.modify_date;
end if;
end
$$
DELIMITER ;
a tabela de bases de dados em que esta corre é acedida e usada por 100's de scripts diferentes no sistema maior e a razão para o trigger é para que não tenha de procurar todos os lugares destes scripts onde o called_count possa ser actualizado...
A minha preocupação é que, porque esta tabela em particular é constantemente modificada (estou falando dezenas de vezes por segundo), isso vai colocar uma pressão indevida na base de dados? Estou está melhor na procura a longo prazo de todas as consultas de actualização do called_ count nos programas miríade e adicionando o daily_called_count = daily_called_count+1 ? Alguns detalhes que eu gostaria de saber a resposta aqui:- o uso deste gatilho faz essencialmente estas 3 consultas de actualização separadas onde já foi uma única consulta, ou o mysql é inteligente o suficiente para agrupar estas consultas? Existe um argumento de desempenho para perseguir e modificar as questões de origem sobre usar o gatilho? Este gatilho pode causar alguma estranheza imprevista que não estou a prever?
2 answers
Duas declarações de exoneração de Responsabilidade:
-
Não trabalho com o MySQL há muito tempo e nunca usei gatilhos com ele. Só posso falar da experiência do general com o RDBMS.
- a única maneira de realmente saber alguma coisa com certeza é fazer um teste de desempenho.
Acho que não é uma actualização separada no sentido de execução de declarações. Mas você está adicionando um custo adicional computacional para cada linha. No entanto, o que mais me preocupa é a natureza linha a linha deste gatilho. Diz literalmente: De um modo geral, as operações "row-by-row" têm uma escala fraca num SGBD em comparação com as operações "SET-based". O servidor de MS SQL executa os accionadores do nível de instruções onde todo o conjunto de linhas afetadas é passado para dentro, então uma operação linha-a-linha não é necessária. Isto pode não ser uma opção nos gatilhos do MySQL - eu realmente não sei.O uso deste dispositivo faz essencialmente com que estas 3 consultas de actualização separadas se situem onde já esteve uma única consulta, ou mysql é inteligente o suficiente para agrupar essas consultas?
Isso faria com que o sistema funcionasse menos. Quanto é o impacto da performance, numericamente, não posso dizer. Terias de testar. Se for apenas uma diferença de 1%, o o trigger deve estar bem. Se for 50%, valeria a pena procurar o código todo. Uma vez que caçar o código é um fardo, suspeito que está incorporado numa aplicação ou vem dinamicamente de um ORM. Se for esse o caso, desde que o custo de desempenho do gatilho seja aceitável, prefiro manter o gatilho uma vez que ele mantém um detalhe específico DB no DB.Existe um argumento de desempenho para perseguir e modificar as consultas de origem sobre o uso do gatilho?
Medida, medida, medida.
Vem-me à mente Caching. Se estas colunas são parte de algo que um aplicativo lê e caches, sua invalidação de cache é provavelmente ligada a quando ele pensa que mudou os dados. Se a base de dados Alterar dados por baixo dela, como com um gatilho, cache pode resultar em dados obsoletos sendo processados.Este gatilho pode causar alguma estranheza imprevista que Não estou a antecipar?
Para notar que estou a usar 10.0.24-MariaDB no nosso servidor de desenvolvimento que não tinha mais nada a correr sobre ele na altura.
Aqui estão os meus resultados...A actualizar 100000 linhas:
TRIGGER QUERY TIME: 6.85960197 SECONDS
STANDARD QUERY TIME: 5.90444183 SECONDS
A actualizar 200000 linhas:
TRIGGER QUERY TIME: 13.19935203 SECONDS
STANDARD QUERY TIME: 11.88235188 SECONDS
Tu as pessoas podem decidir por si mesmas qual o caminho a seguir.