Pular para o conteúdo principal

Questão de Banco de Dados — Consultas e Comandos em SQL — FUNDATEC 2023

Banco de DadosConsultas 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?

  1. AApenas I.
  2. BApenas II.
  3. CApenas III.
  4. DApenas I e II.
  5. 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 é.

Gabarito: letra D

Link permanente: /questoes/qa537511