Pular para o conteúdo principal

Questão de Banco de Dados — Otimização (Tuning) em Banco de Dados — FCC 2026

Banco de DadosOtimização (Tuning) em Banco de Dados
Código
fc142369
Banca
FCC
Órgão
MPE SE
Ano
2026
Cargo
Ana ( )

Um analista precisa otimizar o desempenho da consulta SQL abaixo, que é crítica para o acompanhamento de processos, mas que está apresentando alto custo de execução devido ao volume superior a 10 milhões de registros na tabela Investigacao:

 

SELECT p.nome, COUNT(i.id_investigacao) AS total_investigacoes
FROM Promotor p
INNER JOIN Investigacao i ON p.id_promotor = i.fk_promotor
WHERE i.data_abertura >= '2025-01-01'
GROUP BY p.nome
ORDER BY total_investigacoes DESC;

 

Considerando a necessidade de otimizar, em uma única estrutura de índice na tabela Investigacao, as operações de JOIN (fk_promotor), FILTER (data_abertura) e AGGREGATION (COUNT), a ação de indexação mais completa e tecnicamente adequada para possibilitar um index-only scan (consulta baseada em índice de cobertura) e minimizar o acesso à tabela principal é:

  1. ACREATE INDEX idx_investigacao_id ON Investigacao (id_investigacao);
  2. BCREATE INDEX idx_investigacao_fk_data_id ON Investigacao (fk_promotor, data_abertura, id_investigacao);
  3. CCREATE INDEX idx_investigacao_data ON Investigacao (data_abertura);
  4. DCREATE INDEX idx_investigacao_fk ON Investigacao (fk_promotor);
  5. ECREATE INDEX idx_investigacao_fk_data ON Investigacao (fk_promotor, data_abertura);
Revelar gabarito e comentário

GabaritoB — CREATE INDEX idx_investigacao_fk_data_id ON Investigacao (fk_promotor, data_abertura, id_investigacao);

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: índice de cobertura (covering index)

Gabarito: letra B. Para possibilitar um index-only scan (varredura apenas pelo índice, sem acesso à tabela), o índice composto deve conter todas as colunas referenciadas na consulta: a coluna de junção (fk_promotor), a coluna de filtro (data_abertura) e a coluna de agregação (id_investigacao). O índice (fk_promotor, data_abertura, id_investigacao) cobre exatamente essas três necessidades, permitindo que o SGBD responda à consulta inteiramente pelo índice, minimizando o I/O.

O conceito central aqui é o índice de cobertura (covering index). Um índice é dito "coberto" quando contém todas as colunas necessárias para resolver uma consulta, de modo que o SGBD não precise buscar os dados na tabela principal (heap). Isso reduz drasticamente o custo de execução, especialmente em tabelas com milhões de registros, como a Investigacao com mais de 10 milhões de linhas.

Para entender por que a alternativa B é a correta, é preciso decompor a consulta em suas operações:

  1. JOIN: a junção entre Promotor e Investigacao é feita pela condição p.id_promotor = i.fk_promotor. Para acelerar essa operação, é fundamental ter um índice na coluna fk_promotor da tabela Investigacao.

  2. FILTER: a cláusula WHERE filtra as linhas por data_abertura >= '2025-01-01'. Um índice que inclua data_abertura permite que o SGBD localize rapidamente apenas as linhas que atendem ao filtro, sem varrer a tabela inteira.

  3. AGGREGATION: a função COUNT(i.id_investigacao) precisa contar os registros por grupo. Se o índice incluir id_investigacao, o SGBD pode contar diretamente as entradas do índice, sem acessar a tabela.

A ordem das colunas no índice composto também é relevante. A regra prática é colocar primeiro as colunas usadas em condições de igualdade (JOIN), depois as colunas de filtro por faixa (WHERE com >=), e por fim as colunas de projeção/agregação. Isso porque o índice é organizado de forma que as colunas iniciais determinam a ordenação, permitindo buscas eficientes por igualdade e, em seguida, por faixa.

Um exemplo prático: imagine que a tabela Investigacao tenha 10 milhões de linhas. Sem índice, o SGBD precisaria ler todas as 10 milhões de linhas para aplicar o filtro de data e fazer a junção. Com o índice (fk_promotor, data_abertura, id_investigacao), o SGBD pode percorrer apenas as entradas do índice que correspondem aos promotores e às datas relevantes, contando os id_investigacao diretamente. O acesso à tabela principal é eliminado, reduzindo o I/O de milhões de leituras para algumas centenas ou milhares.

A pegadinha desta questão está em reconhecer que o índice precisa ser composto e cobrir todas as colunas. Alternativas que criam índices em apenas uma coluna (A, C, D) ou em duas colunas (E) não são suficientes para um index-only scan, pois o SGBD ainda precisaria acessar a tabela para obter a coluna que falta. A alternativa B é a única que inclui as três colunas necessárias.

Guarde este critério: para um covering index, o índice deve conter todas as colunas da consulta (SELECT, WHERE, JOIN, GROUP BY, ORDER BY). É exatamente essa completude que separa a alternativa correta das demais.

Alternativa

Índice proposto

Cobre JOIN (fk_promotor)

Cobre FILTER (data_abertura)

Cobre COUNT (id_investigacao)

Permite index-only scan?

A

(id_investigacao)

B

(fk_promotor, data_abertura, id_investigacao)

C

(data_abertura)

D

(fk_promotor)

E

(fk_promotor, data_abertura)

1Requisito
Todas as colunas da consulta
SELECT, WHERE, JOIN, GROUP BY
2Ordem das colunas
Igualdade (JOIN)
Faixa (WHERE)
Projeção/agregação (COUNT)
3Benefício
Index-only scan
Sem acesso à tabela (heap)
Índice de cobertura (covering index)
LEVELsoulevel.com.br
Índice de cobertura (covering index): Requisito (Todas as colunas da consulta, SELECT, WHERE, JOIN, GROUP BY); Ordem das colunas (Igualdade (JOIN), Faixa (WHERE), Projeção/agregação (COUNT)); Benefício (Index-only scan, Sem acesso à tabela (heap))

Alternativa A — ❌ Incorreta

Cria um índice apenas na coluna id_investigacao. Essa coluna é usada apenas na função COUNT, mas o índice não cobre a coluna de junção fk_promotor nem a de filtro data_abertura. O SGBD ainda precisaria acessar a tabela para aplicar o filtro e fazer a junção, impossibilitando um index-only scan.

Alternativa B — ✅ Correta ⟵ GABARITO

Cria um índice composto com as três colunas necessárias: fk_promotor (JOIN), data_abertura (FILTER) e id_investigacao (COUNT). Com esse índice, o SGBD pode resolver a consulta inteiramente pelo índice, sem acessar a tabela principal. A ordem das colunas também é adequada: primeiro a coluna de igualdade (JOIN), depois a de faixa (WHERE), e por fim a de agregação.

Alternativa C — ❌ Incorreta

Cria um índice apenas na coluna data_abertura. Embora acelere o filtro por data, não cobre a coluna de junção fk_promotor nem a de agregação id_investigacao. O SGBD precisaria acessar a tabela para obter essas colunas, inviabilizando o index-only scan.

Alternativa D — ❌ Incorreta

Cria um índice apenas na coluna fk_promotor. Acelera a junção, mas não cobre o filtro por data_abertura nem a agregação por id_investigacao. O acesso à tabela principal ainda seria necessário, impedindo o index-only scan.

Alternativa E — ❌ Incorreta

Cria um índice composto com fk_promotor e data_abertura, cobrindo JOIN e FILTER. No entanto, falta a coluna id_investigacao, usada na função COUNT. O SGBD precisaria acessar a tabela para contar os registros, o que impede o index-only scan completo.

PEGA ESSA DICA!

Para identificar um covering index em questões de otimização, liste todas as colunas que aparecem na consulta (SELECT, WHERE, JOIN, GROUP BY, ORDER BY) e verifique se o índice proposto contém todas elas. Se faltar qualquer uma, o índice não é de cobertura.

Gabarito: letra B

Link permanente: /questoes/fc142369