Com razoável frequência alguém levanta a ideia de usar stored procedures (procs, para abreviar) porque melhora segurança e performance.
Como eu sei que isso não é verdade, e o assunto é levantado sempre, vou escrever esse post, depois é só linkar.
Geralmente as consultas via procs são comparadas com queries feitas com texto SQL, que vou chamar de ad-hoc. Esse tipo de consulta é aquela onde você escreve “SELECT Id, Campo FROM Cliente WHERE Id = 1” e manda direto para o banco, e é também o usado por mapeadores objeto relacional (ORMs).
Vamos aos mitos:
- Stored Procedures permitem fazer cache do plano de execução, enquanto consultas ad-hoc não permitem
Mito. Os planos de execução são armezanados para reutilização em procs e também em consultas ad-hoc. Vejam essa afirmação do MSDN:
“In SQL Server 2000, whenever a statement within a batch causes recompilation, the whole batch, whether submitted through a stored procedure, trigger, ad-hoc batch, or prepared statement, is recompiled. In SQL Server 2005 and later, only the statement inside the batch that causes recompilation is recompiled.” Daqui.
Esse outro artigo entra mais a fundo. Notem que o importante é o uso de parâmetros, não só para evitar o SQL Injection, mas também para permitir o cache do plano de execução (algo que o SQL Server 2008 já tenta resolver, mesmo se você não enviar o parâmetro). - Stored Procedures estimulam reusabilidade.
Mito. Reusabilidade pode ser atingida de diversas formas. Um modelo procedural, como o da programação de um banco de dados relacional, possibilita reusabilidade dentro deste paradigma. Eu prefiro estimular reusabilidade com OO, mas isso não quer dizer que não podemos reutilizar tanto em um quanto no outro. - Stored Procedures ajudam a encapsular regras de negócio.
Mito. Eu posso encapsular, com mais produtividade na programação, em um modelo OO. - Stored Procedures são mais seguras. Com procs você pode remover os direitos a insert, update, delete e consulta, inclusive com granularidade na coluna de uma tabela.
Mito. Ainda que seja possível fazer isso, se em uma operação de negócio o usuário precisa atualizar um campo, ele terá que ter acesso de atualização deste campo, se não direto, indiretamente pela proc. Isso fica ainda mais irrelevante quando vemos aquelas procs de CUD, ou seja, quando o programador cria 3 procs, uma para cada operação do CUD, e simplesmente pega os parâmetros e repassa para as declarações de insert, update e delete. A proc nesse caso é um mero proxy. A outra opção é colocar a regra de negócio no banco, algo absurdo na maioria dos cenários (não vou me aprofundar no porquê, vai ficar para outro post). - Stored Procedures diminuem o consumo de banda, já que a consulta que vai ao banco é somente o nome da proc e seus parâmetros.
Meia verdade. De fato a operação que vai ao banco é menor. Mas em uma operação de consulta, o maior peso está no retorno da consulta, cheio de dados, e não na solicitação, que é um texto curto. A diferença entre a consulta com proc e sem chega a ser ridícula. E em uma operação de atualização do banco, os dados que vão subir tem que ser enviados da mesma forma, e o resto da declaração de uma operação ad-hoc é só um pouco maior se comparado com a proc. Além disso, nas redes de hoje, com servidores web ao lado de servidores de banco em rede gigabit, o gargalo não fica na rede.
Além destes mitos, o que mais me incomoda é que procs praticamente impedem o uso de ORMs. E ORMs são praticamente obrigatórios em um projeto que quer ter um mínimo de produtividade. Escrever SQL na mão hoje em dia é algo absolutamente desnecessário para 90% das aplicações, e nos 10% que sobram, só um pequeno percentual teria algum ganho sobre o uso de SQL manual sobre um ORM. Mas isso fica para outro post também.
Um caso onde vejo uso de procs como útil: ETL (veja update 1 abaixo). Geralmente é muito difícil fazer carga de grandes massas de dados via interação com o client, seja ele .Net, Java, C++, VB6, ou o que for. O ideal é a carga acontecer no banco, e aí procs vão bem. O maior problema, derivado do ETL, é a duplicação de regras de negócio, já que uma operação de negócio que entra via carga externa estará sujeita às mesmas regras de uma entrada manual, normalmente também permitida. É algo que aumenta o custo de manutenção, mas muitas vezes não tem jeito.
É isso. Joguem as procs no lixo, programem com ORMs (ou bancos NOSQL), e sejam produtivos.
Update 1: O Gustavo Maia Aguiar, MVP de SQL, levanta que procs não são boas para ETL, e expõe vários motivos. Vejam nos comentários.
Update 2: O Luciano Moreira (Luti), também MVP de SQL, também responde a este post, mas com outro post. Imperdível se você gostou da discussão.
Giovanni Bassi
Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.