Multicolunas em cláusula IN
A boa prática é fundamental para qualquer tipo de programação. E boa prática abrange uma infinidade de ações e métodos para tornar seu código mais legível, enxuto, performático e com fácil manutenibilidade. E ainda, tudo isso pode ser visto de forma diferente por cada pessoa. O que é fácil para mim pode parecer difícil para outros e vice-versa.
Existem diversas práticas que facilitam a codificação de SQL em Oracle, permitindo que resuma – em menores instruções – diversas condicionais na cláusula WHERE. Na contra-mão é notório também a não utilização destas, seja por muitas vezes ser algo específico da tecnologia Oracle – ora não cabendo em SQL padrão ANSI – ou por simplesmente pouca divulgação e exemplos práticos. Aqui listo alguns exemplos:
- Multitable Inserts – o qual também já fiz um artigo sobre. Clique aqui para ler.
- Instrução Merge;
- Lateral (disponível a partir da versão Oracle 12.)
- Multicolunas em cláusula IN;
O último listado – Multicolunas em cláusula IN – será tema deste artigo, onde mostrarei exemplo prático da sua utilização, resolvendo um caso clássico de OR enfileirados.
Tendo com base o ambiente HR, foi elaborada a demanda de efetuar uma consulta para saber salários com valores R$ 9000,00, R$ 4800,00 e R$ 8200,00 para cargos e departamentos específicos, não obedecendo uma lógica global, mas sim regras específicas para cada situação. A query comumente utilizada utiliza-se o padrão abaixo:
SELECT * FROM hr.employees
WHERE (salary = 9000 AND job_id = 'IT_PROG' AND department_id = 60) OR
(salary = 4800 AND job_id = 'IT_PROG' AND department_id = 60) OR
(salary = 8200 AND job_id = 'FI_ACCOUNT' AND department_id = 100);
Nota-se que é um caso simples, com apenas 3 variações de filtros com OR enfileirados. Mas imagine que possam ter 10, 20, 30 e assim por diante, de tais condicionantes para a query, o que poderia transformar a query em um monstro e uma segunda pessoa teria que ler cada expressão entre parêntese para entender o que estava ocorrendo, além, de, hipoteticamente, existir a necessidade de adicionar mais um campo para cada condição, tornando uma atividade repetitiva.
Neste sentido, apresento Multicolunas em cláusula IN o qual permite produzir uma query mais legível e de fácil manutenibilidade. Existe apenas um conjunto agrupado de todas as colunas que deverão ser filtradas, acompanhado do IN e, por fim, os conteúdos a serem considerados. O exemplo prático vemos abaixo:
SELECT * FROM hr.employees
WHERE (salary, job_id, department_id) IN ( (9000, 'IT_PROG', 60),
(4800, 'IT_PROG', 60),
(8200, 'FI_ACCOUNT', 100));
O resultado é o mesmo, sendo listadas 4 linhas com as mesmas informações, para ambos os casos.
Partindo para comparação de performance é visto que não existem grandes variações entre os dois modelos de instruções. Conforme exemplo abaixo, nota-se que os planos de execuções das duas querys são idênticos:
– Query SEM In Multicolunas
– Query COM In Multicolunas
Ao consultar também o 10053 Trace nota-se que a instrução final após as transformações é a mesma, sem quaisquer variações:
– Query SEM In Multicolunas
– Query COM In Multicolunas
Por fim, a escolha da utilização de IN Multicolunas não deve ser levado pelo fato de performance, mas apenas como critérios de boa prática e manutenibilidade de códigos.
Referências