Gostaria de perguntar sua opinião sobre a implementação de um formulário de pesquisa filtrado. Vamos imaginar o seguinte caso:
- 1 mesa grande com muitas colunas
- Pode ser importante dizer que este SQL Server
Você precisa implementar um formulário para pesquisar dados nesta tabela e, neste formulário, você terá várias caixas de seleção que permitem costumizar essa pesquisa.
Agora, minha pergunta aqui é qual das seguintes opções deve ser a melhor maneira de implementar a pesquisa?
Crie um procedimento armazenado com uma consulta dentro. Este procedimento armazenado verificará se os parâmetros são fornecidos pelo aplicativo e, no caso em que não recebem um curinga, serão colocados na consulta.
Crie uma consulta dinâmica, criada de acordo com o que é fornecido pelo aplicativo.
Estou perguntando isso porque sei que o SQL Server cria um plano de execução quando o procedimento armazenado é criado, a fim de otimizar seu desempenho, no entanto, criando uma consulta dinâmica dentro do procedimento armazenado, sacrificaremos a otimização obtida pelo plano de execução?
Por favor, diga-me qual seria a melhor abordagem em sua opinião.
Respostas:
Convém consultar a resposta para esta pergunta semelhante aqui: /programming/11329823/add-where-clauses-to-sql-dynamically-programmatically
Descobrimos que um SPROC que utiliza vários parâmetros opcionais e implementa o filtro da seguinte maneira:
armazenará em cache o primeiro plano de execução com o qual é executado (por exemplo
@optionalParam1 = 'Hello World', @optionalParam2 = NULL
), mas executará miseravelmente se passarmos a ele um conjunto diferente de parâmetros opcionais (por exemplo@optionalParam1 = NULL, @optionalParam2 = 42
). (E, obviamente, queremos o desempenho do plano em cache, entãoWITH RECOMPILE
está fora)A exceção aqui é que, se houver TAMBÉM pelo menos um filtro OBRIGATÓRIO na consulta que seja ALTAMENTE seletivo e indexado adequadamente, além dos parâmetros opcionais, o PROC acima funcionará bem.
No entanto, se TODOS os filtros forem opcionais, a terrível verdade é que o sql dinâmico parametrizado realmente funciona melhor (a menos que você escreva N! PROCS estático diferente para cada permutação de parâmetros opcionais).
SQL dinâmico como o abaixo criará e armazenará em cache um plano diferente para cada permutação dos parâmetros de consulta, mas pelo menos cada plano será 'adaptado' à consulta específica (não importa se é um PROC ou Adhoc SQL - como desde que sejam consultas parametrizadas, elas serão armazenadas em cache)
Portanto, portanto, minha preferência por:
etc. Não importa se passamos parâmetros redundantes para sp_executesql - eles são ignorados. Vale ressaltar que ORMs como Linq2SQL e EF usam sql dinâmico parametrizado de maneira semelhante.
fonte
Comece com o que você acha que é mais fácil de implementar (acho que a opção 2). Em seguida, meça o desempenho dos dados do mundo real. Comece a otimizar apenas quando necessário, não antes.
A propósito, dependendo da complexidade dos seus filtros de pesquisa, sua tarefa pode não ser facilmente resolvida sem o SQL dinâmico. Portanto, mesmo quando você usa um procedimento armazenado, isso provavelmente não aumenta o desempenho, como você já suspeita. Por outro lado, se ajudar, existem vários tipos de dicas (consulte http://www.simple-talk.com/sql/performance/controlling-execution-plans-with-hints/ ) que você pode adicionar a um SQL consulta, dinâmica ou não, para ajudar o SQL Server a otimizar seu plano de execução.
fonte