Quando é melhor descarregar o trabalho no RDBMS em vez de fazê-lo no código?

12

Tudo bem, vou entender: sou um codificador melhor do que em bancos de dados e fico imaginando onde estão as "melhores práticas" sobre o assunto de fazer cálculos "simples" na consulta SQL vs. o código, como este exemplo do MySQL (eu não o escrevi, só preciso mantê-lo!) - Isso retorna o nome de usuário e a idade dos usuários a partir do último evento.

SELECT u.username as user, 
       IF ((DAY(max(e.date)) - DAY(u.DOB)) < 0 ,   
       TRUNCATE(((((YEAR(max(e.date))*12)+MONTH(max(e.date)))
       -((YEAR(u.DOB)*12)+MONTH(u.DOB)))-1)/12, 0),  
       TRUNCATE((((YEAR(max(e.date))*12)+MONTH(max(e.date))) -            
       ((YEAR(u.DOB)*12)+MONTH(u.DOB)))/12, 0)) AS age   
FROM users as u
JOIN events as e ON u.id = e.uid
...

Comparado a fazer o levantamento "pesado" no código:

Inquerir:

SELECT u.username, u.DOB as dob, e.event_date as edate
FROM users as u
JOIN events as e ON u.id = e.uid

código:

function ageAsOfDate($birth, $aod)
{    //expects dates in mysql Y-m-d format...
     list($by,$bm,$bd) = explode('-',$birth);
     list($ay,$am,$ad) = explode('-',$aod);

     //Insert Calculations here 
     ...
     return $Dy; //Difference in years
}

echo "Hey! ". $row['user'] ." was ". ageAsOfDate($row['dob'], $row['edate']) . " when we last saw him."; 

Tenho certeza de que, em um caso simples como esse, não faria muita diferença (além do arrepiante sentimento de horror quando preciso fazer alterações em consultas como a primeira), mas acho que fica mais claro o que eu ' estou procurando.

Obrigado!

GeminiDomino
fonte
1
Essa é uma boa pergunta - me deparei com o mesmo problema.
Michael K
Aqui está um bom exemplo de quando não fazê-lo: calendar.sql (. Sim, essa é a minha monstruosidade, sim, que era uma má idéia, e não, não é lento)
greyfade
Vocês estão lançando deuses ... Aposto que o MD5 acaba sendo "CthulhuFhtagn"
GeminiDomino

Respostas:

13

Você deseja executar todas as operações baseadas em conjunto no banco de dados por motivos de desempenho. Então, funções de agregação, funções de classificação, junções etc.

Este cálculo de idade, eu faria em código. A única razão pela qual eu poderia fazer algo assim em uma consulta ao banco de dados é se exigisse muitas colunas que, de outra forma, eu não selecionaria, que poderiam realmente gerar dados suficientes para desacelerar significativamente minha consulta. Selecionar alguns valores inteiros não fará uma diferença significativa de desempenho. E mesmo que isso faça uma diferença de desempenho moderada, serei inclinado a manter essa lógica no código do aplicativo.

Jeremy
fonte
Concordo. O código que brinca com valores para fins de exibição deve estar no código do seu aplicativo.
TehShrike
4

Cada caso é diferente

É a lógica ...

  • necessário por outros clientes? SECO: no banco de dados
  • usado para processamento adicional? por exemplo, classificar por idade decrescente: no banco de dados
  • requer configurações regionais? dd / mm / aaaa ou mm / dd / aaaa: no cliente
  • usado frequentemente? Por que calculá-lo repetidamente: use a coluna computada e persistida no banco de dados

No presente caso, eu poderia usar uma coluna computada e persistente no banco de dados

Poderia ser pior: você pode ter isso no banco de dados:

"Hey! ". u.username." was ". <datecalc>. " when we last saw him."
gbn
fonte
3

Basicamente, você deve considerar duas coisas: uso da CPU e tráfego de rede. Você não deve gerar respostas enormes, transferi-las pela rede e resumir no front-end, pois o banco de dados pode fazer isso muito melhor.

Para manipulação de dados , é uma troca. Se o banco de dados gasta uma quantidade comparável de ciclos de CPU com o código de front-end, fazendo a mesma coisa - considerando que a quantidade de dados transferidos é aproximadamente equivalente), não importa onde. Em seguida, faça-o onde tiver a maior quantidade de conhecimento em programação. Freqüentemente, você pode percorrer um longo caminho com uma seleção cuidadosa e isso pode ser muito útil.


fonte
1

Você mencionou uma: área de especialização. Talvez a estrutura do banco de dados não seja muito intensa, então você decide transferir parte do desenvolvimento lógico para um membro da equipe que seja mais centralizado no banco de dados. Pode não ser o ideal, mas se você estiver com problemas de tempo ...

O hardware do banco de dados possui significativamente mais recursos que outros servidores e você não pode alterar isso. Isso pode não se aplicar a essa situação específica, mas pode precisar ser considerado.

Existem outros aplicativos que podem precisar da lógica fora do seu código. Algumas ferramentas de gravação de relatórios podem não ser capazes de utilizar um serviço da Web ou uma API. Você pode duplicar a lógica ou se achar que os requisitos podem divergir.

JeffO
fonte
"O hardware do banco de dados tem significativamente mais recursos que outros servidores e você não pode mudar isso." - eh? De onde vieram essas duas declarações?
precisa
Acho que Jeff pode estar falando sobre servidores de banco de dados independentes. Eu provavelmente deveria ter especificado que trabalho principalmente nas configurações do LA [MP] P.
GeminiDomino
1
Uma configuração do LAMP não é motivo para não ter um servidor de banco de dados independente e nem um servidor de banco de dados independente é uma garantia de mais recursos nem de poder mudar isso.
precisa
Hrm. Não tenho certeza então.
GeminiDomino
@ Peter Boughton, DB e aplicativo no mesmo servidor têm ordem de magnitude menor que o tempo para a conexão da interface e magnitudes maiores de E / S por toda parte, existem razões reais para localizar esses dois juntos.
Jé Queue
0

Eu sempre erro em colocar tanto processamento no DB. Sua sintaxe acima também pode ser escrita com funções de banco de dados que seriam uma solução muito limpa para a IMO.

Jé Queue
fonte