Em 16-09-2013 15:51, Eden Cardim escreveu:
"Alceu" == Alceu R de Freitas <[email protected]> writes:
Alceu> Quem precisa reler com mais atenção é você: se você critica
Alceu> que usar stored procedures é uma otimização prematura e
Alceu> depois muda de ideia... bem, decida-se.
Ok, vamos pro "be-a-bá", olha o aviãzinho! Seguinte:
Eden,
Primeiramente, você devia parar de usar cuecas apertadas: as pessoas vão
gostar mais de você.
Eu conheço o Solli (na medida do que é possível conhecer por participar
em eventos sociais comuns) então acho que ele já fez todo o racional que
você colocou aqui antes de postar para a lista. Vamos em frente agora...
1 - Usar SPs como implementação inicial de uma funcionalidade de
cadastro é uma otimização prematura. Os motivos são:
1.1 - SPs raramente são portáveis entre implementações de backend.
1.2 - SPs aumentam a quantidade de trabalho envolvido no deploy
do banco de dados.
1.3 - SPs significam mais partes móveis, o que significa que mais
pontos de integração precisam ser testados.
1.4 - SPs podem sim ser mais lentas do que select+insert porque a
depender do caso, você precisa preservar locks durante a SP inteira e
o backend não tem como otimizar pra você, então é melhor que você seja
*muito bom* se for seguir esse caminho.
Concordo com todos os pontos, exceto o 1.4: DBI e DBIx::Class vão estar
sujeitos ao mesmo problema. Eu não manjo muito de stored procedures em
outros bancos, mas no Oracle consigo ter controle granular de transação,
então não vejo este problema que você levanta.
Bom, agora que revisamos o *básico*, vamos pra segunda parte:
Que bom que você se deu ao trabalho de ajudar os monges mais novos! É
muito chato quando você escreve respostas achando que todos devem
concordar com você sem um racional!
"In God we thrust: all others must bring data".
2 - *se* (repito: *se*, condicional, ramificação) for constatado que
uma SP for de fato necessária como otimização (e repito, sãos raros os
casos) somente aí você sobrecarrega as partes relevantes das classes
envolvidas e chama a tua SP lindamente otimizada, mas só no ponto em
que estiver lento, não precisa arrancar o DBIx::Class inteiro.
Eu não me lembro de ter dito para arrancar o DBIx::Class inteiro... onde
foi que eu escrevi isto mesmo?
Bom, se não houvesse um motivo simples pra ignorar essa recomendação,
eu explicaria as outras desvantagens. O motivo simples é que um cache
como o memcached não é necessário pelo fato de que qualquer kernel
lançado a partir da década de 90 faz page caching pra você e faz de
uma forma muito mais eficiente que o memcached faria. O kernel pode
fazer isso porque ele tem acesso transacional a todos os pontos de
entrada e saída de dados do sistema. O memcached não tem.
Cache != Memcached
Eu sei que todo mundo gosta do Memcached e acha bonito (eu incluso) mas
para ter/usar cache existem N estratégias disponíveis...
Novamente, um banco de dados pode fazer isso *internamente* porque ele
tem acesso transacional a todos os dados do banco, o memcached não
tem. E sim, os dados de um cache qualquer são *todos* transientes
porque a hierarquia de memória proíbe que *todos* os dados sejam
armazenados no cache: o custo é proibitivo. Logo, se a demanda
imediatata do sistema é por um volume de dados que ocupe todo o cache
disponível e que não sejam as siglas de UF, essas siglas vão
desaparecer do cache até que sejam requisitadas novamente.
Não entendi muito bem, mas acho que não quero perguntar mais...
O problema é que se você tem um banco de dados que precisa ser
otimizado via cache externo, é bem provável que os registros de
cadastro não caibam todos na memória. O memcached não pode fazer isso
porque ele não tem acesso transacional (repetindo pra garantir que
leram dessa vez).
Você deve ter razão... ou não! Versões mais recentes do MySQL já te dão
opção de instalar ele junto com o Memcached. Deve ser para evitar
acessar o banco de dados em situações como UF.
Falácia do espantalho? Isso é um cenário completamente diferente do
que está sendo discutido. A questão é que a *chave* ser única não te
salva de ter que fazer uma consulta antes de tentar inserir uma
duplicata. E nesse discussão específica, essa chave não é composta: é
o email.
Não, eu não lembrava mesmo do e-mail original do Solli. Fiquei com
preguiça de procurar também. Mas realmente não te salva de fazer a
consulta, exceto claro, se você capturar a exceção que o banco vai gerar
quando tentar inserir o e-mail de novo.
Você está ignorando os contra-pontos que já foram expostos na thread
antes, vou sintetizar aqui pra você (e pela última vez):
Não, eu não ignorei e comentei todos na medida do possível. A diferença
é que eu não uso cuecas apertadas.
Consultar antes do insert:
1 - é trivial
É mesmo!
2 - é rápido (tanto a implementação quanto a execução, assumindo o uso
de um banco de dados razoável)
É rápido... comparado ao que? A capturar uma exceção?
3 - é portável
Se eu usar ANSI SQL. E se o banco que decidir usar suportar o ANSI SQL
(acho que todos suportam, mas enfim).
4 - é simples de ler (select email from tabela where email = '[email protected]'
é a primeira coisa que se aprende em qualquer curso vagabundo de SQL)
É mesmo! Inclusive o resultado desta query poderia ser guardado no seu
cache favorito para evitar ter que ir até o banco de dados, atravessando
todas as camadas do DBIx::Class até o motor do BD.
Um mecanismo de excessões:
1 - Não é tão rápido assim (a resolução da pilha é particularmente
lenta, em qualquer linguagem)
Tem alguma referência que mostre isto? Eu não tenho a menor ideia mas
gostaria de entender melhor.
Pensando melhor, deixa para lá. Eu vou no Google mesmo.
2 - Não é portável (cada banco de dados tem seus próprios códigos de
erro)
Realmente.
3 - Não é trivial (requer conhecimento específico de todas as engines
de banco de dados envolvidos e requer um mecanismo de excessões
bem-planejado e funcional)
Idem.
Não tem *nada* a favor das excessões nesse caso, exceto pra quem nunca
programou em nada além de java a vida inteira, aí *talvez* faça sentido.
Isso é um pouco de ranço, não? Exceções é algo que sinto bastante falta
no Perl simplesmente porque lidar com $@ é meio que um saco.
C# também usa. Python também.
Conclusões sobre esta thread:
1 - É difícil ter desempenho superior sem sacrificar alguma coisa, como
abstração ao banco de dados. Geralmente uma solução híbrida funciona
melhor do que tentar procurar pela bala da prata.
2 - Não quero mais saber desta thread. O Solli que "se vire", vou ler a
thread sobre "o melhor dos melhores do mundo" que está mais divertida.
[]'s
Alceu
=begin disclaimer
Sao Paulo Perl Mongers: http://sao-paulo.pm.org/
SaoPaulo-pm mailing list: [email protected]
L<http://mail.pm.org/mailman/listinfo/saopaulo-pm>
=end disclaimer