Questão de Banco de Dados — Consultas e Comandos em SQL — FUNDATEC 2023
Banco de Dados›Consultas e Comandos em SQL
Código
qa537511
Banca
FUNDATEC
Órgão
BRDE
Ano
2023
Cargo
Ana Sist ( )
Considere a tabela EMPREGADOS definida abaixo em SQL.
Create table EMPREGADOS
(CODEMP INT PRIMARY KEY,
NOMEEMP VARCHAR(300) NOT NULL UNIQUE,
FUNCAO INT CHECK(FUNCAO BETWEEN 1 AND 5),
SALARIO FLOAT NOT NULL,
DEPTO INT NOT NULL);
Sobre esta tabela, foi definido um índice primário (codemp – chave primária), e dois índices secundários, um sobre nomeemp, e outro sobre funcao.
Uma pessoa do desenvolvimento reclamou à DBA que algumas de suas consultas sobre essa tabela estavam muito demoradas, e pediu apoio para melhoria do desempenho. A DBA examinou o plano de execução das consultas e, em vez de uma solução sobre o esquema da base de dados, sugeriu a reescrita das consultas.
ORIGINAL
REESCRITA
I.
SELECT NOMEEMP, FUNCAO, DEPTO
FROM EMPREGADOS
WHERE SUBSTR(NOMEEMP, 1, 5) =
'MARIA';
SELECT NOMEEMP, FUNCAO, DEPTO
FROM EMPREGADOS
WHERE NOMEEMP LIKE 'MARIA%';
II.
SELECT NOMEEMP
FROM EMPREGADOS
WHERE FUNCAO <> 5;
SELECT NOMEEMP
FROM EMPREGADOS
WHERE FUNCAO BETWEEN 1 and 4;
III.
SELECT DISTINCT NOMEEMP, SALARIO,
DEPTO
FROM EMPREGADOS
WHERE FUNCAO = 1;
SELECT NOMEEMP, SALARIO, DEPTO
FROM EMPREGADOS
WHERE FUNCAO = 1;
Qual, dentre as consultas reescritas, melhorou o desempenho da consulta original porque resultou, no plano de consulta, em uma operação (mais eficiente) sobre um índice?
AApenas I.
BApenas II.
CApenas III.
DApenas I e II.
EI, II e III.
Revelar gabarito e comentário▾
GabaritoD — Apenas I e II.
Comentário gerado por IA. É um apoio ao estudo, ancorado em fontes, mas pode conter imprecisões — confira sempre na fonte oficial (lei, súmula, edital e gabarito da banca). Encontrou um erro? Use “Reportar”.
Otimização de Consultas SQL e Uso de Índices
Gabarito: letra D. As reescritas I e II melhoram o desempenho porque transformam condições que impedem o uso de índices em condições que permitem a busca por índice (sargable). A reescrita I troca SUBSTR(NOMEEMP, 1, 5) = 'MARIA' por NOMEEMP LIKE 'MARIA%', permitindo o uso do índice secundário em NOMEEMP. A reescrita II troca FUNCAO <> 5 por FUNCAO BETWEEN 1 AND 4, permitindo o uso do índice em FUNCAO. A reescrita III apenas remove o DISTINCT, o que não altera a capacidade de usar índice, pois a condição FUNCAO = 1 já era sargable.
O cerne da questão é o conceito de sargable (Search ARGument ABLE), que se refere à capacidade de uma condição em uma cláusula WHERE ser avaliada usando um índice. Uma condição é sargable quando o SGBD pode aplicar a busca diretamente sobre os valores indexados, sem precisar ler cada linha da tabela (full table scan) e aplicar a função ou operação sobre o valor armazenado. Quando uma função é aplicada sobre a coluna (como SUBSTR(NOMEEMP, 1, 5)), o SGBD não consegue usar o índice, pois o índice armazena os valores originais, não o resultado da função. Da mesma forma, operadores de negação como <> (diferente) geralmente não são sargable, pois o índice é otimizado para buscas por igualdade ou faixa, e a negação exigiria varrer todo o índice.
Na prática, quando a DBA reescreve a consulta, ela está transformando condições não-sargable em sargable, permitindo que o otimizador escolha uma operação de busca por índice (index seek) em vez de uma varredura completa (index scan ou table scan). Isso reduz drasticamente o número de páginas lidas do disco, melhorando o desempenho. Por exemplo, na consulta I, a condição original SUBSTR(NOMEEMP, 1, 5) = 'MARIA' força o SGBD a ler todas as linhas, calcular a função SUBSTR para cada uma e comparar com 'MARIA'. A reescrita NOMEEMP LIKE 'MARIA%' permite que o SGBD use o índice em NOMEEMP para localizar diretamente os registros que começam com 'MARIA', percorrendo apenas a parte relevante do índice.
A distinção crucial é entre condições que permitem o uso de índice (sargable) e as que não permitem (non-sargable). As principais condições sargable incluem: igualdade (=), comparações de faixa (>, >=, <, <=, BETWEEN), e LIKE com prefixo fixo (padrão que não começa com curinga). As condições não-sargable incluem: uso de funções sobre a coluna (SUBSTR, UPPER, LOWER, etc.), operadores de negação (<>, !=, NOT IN, NOT LIKE), e LIKE com curinga no início ('%MARIA'). A banca explora exatamente essa distinção: o candidato que não conhece o conceito de sargable pode achar que todas as reescritas melhoram o desempenho, mas a reescrita III não tem relação com índice, apenas remove uma operação de eliminação de duplicatas.
Guarde a fronteira entre condições sargable e non-sargable: é exatamente nela que as alternativas se dividem. A reescrita I e II transformam condições non-sargable em sargable, enquanto a III não altera a sargabilidade da condição original.
Reescrita
Condição original
Condição reescrita
Sargable (original)
Sargable (reescrita)
Permite uso de índice?
I
SUBSTR(NOMEEMP, 1, 5) = 'MARIA'
NOMEEMP LIKE 'MARIA%'
Não
Sim
Sim (índice em NOMEEMP)
II
FUNCAO <> 5
FUNCAO BETWEEN 1 AND 4
Não
Sim
Sim (índice em FUNCAO)
III
FUNCAO = 1 (com DISTINCT)
FUNCAO = 1 (sem DISTINCT)
Sim
Sim
Não altera (já usava índice)
Alternativa A — ❌ Incorreta
Afirma que apenas a reescrita I melhorou o desempenho. A reescrita II também melhora, pois transforma FUNCAO <> 5 (non-sargable) em FUNCAO BETWEEN 1 AND 4 (sargable), permitindo o uso do índice em FUNCAO. Portanto, a alternativa está incorreta por omitir a reescrita II.
Alternativa B — ❌ Incorreta
Afirma que apenas a reescrita II melhorou o desempenho. A reescrita I também melhora, pois transforma SUBSTR(NOMEEMP, 1, 5) = 'MARIA' (non-sargable) em NOMEEMP LIKE 'MARIA%' (sargable), permitindo o uso do índice em NOMEEMP. Portanto, a alternativa está incorreta por omitir a reescrita I.
Alternativa C — ❌ Incorreta
Afirma que apenas a reescrita III melhorou o desempenho. A reescrita III apenas remove o DISTINCT, o que não tem relação com o uso de índices. A condição FUNCAO = 1 já era sargable na consulta original, então a reescrita não altera a operação sobre o índice. As reescritas I e II são as que efetivamente melhoram o desempenho por permitirem o uso de índices. Portanto, a alternativa está incorreta.
Alternativa D — ✅ Correta ⟵ GABARITO
As reescritas I e II melhoram o desempenho porque transformam condições non-sargable em sargable, permitindo o uso dos índices secundários em NOMEEMP e FUNCAO. A reescrita I troca SUBSTR(NOMEEMP, 1, 5) = 'MARIA' por NOMEEMP LIKE 'MARIA%', e a reescrita II troca FUNCAO <> 5 por FUNCAO BETWEEN 1 AND 4. Ambas permitem que o otimizador use uma operação de busca por índice (index seek) em vez de uma varredura completa. A reescrita III não tem relação com índices, pois apenas remove o DISTINCT, e a condição FUNCAO = 1 já era sargable.
Alternativa E — ❌ Incorreta
Afirma que as reescritas I, II e III melhoraram o desempenho. A reescrita III não melhora o desempenho relacionado a índices, pois apenas remove o DISTINCT, que não afeta a capacidade de usar o índice em FUNCAO. A condição FUNCAO = 1 já era sargable na consulta original. Portanto, a alternativa está incorreta por incluir a reescrita III.
NÃO CAIA NESSA!
A banca explora a confusão entre remover DISTINCT e melhorar o uso de índices. O candidato pode pensar que qualquer reescrita que simplifique a consulta melhora o desempenho, mas a melhoria real vem da transformação de condições non-sargable em sargable. A reescrita III apenas remove uma operação de eliminação de duplicatas, que não tem relação com a capacidade de usar o índice. Fique atento: DISTINCT não impede o uso de índice, e sua remoção não torna a consulta mais eficiente em termos de acesso a dados.
PEGA ESSA DICA!
Para identificar se uma reescrita melhora o uso de índice, verifique se a condição na cláusula WHERE é sargable. Condições com funções sobre a coluna (como SUBSTR, UPPER) ou operadores de negação (<>, !=) não permitem uso de índice. Reescreva-as para formas equivalentes que usem igualdade, faixa ou LIKE com prefixo fixo. Por exemplo, UPPER(NOME) = 'JOÃO' pode ser reescrita como NOME = 'JOÃO' se os dados já estiverem em maiúsculas, ou criar um índice funcional. Lembre-se: BETWEEN é sargable, <> não é.