Otimizando o desempenho de consulta de data warehouse por filtragem de bitmap

A maioria consultas de data warehouse é projetada para seguir um esquema em estrela e podem processar centenas de milhões de linhas em uma única consulta. Por padrão, o otimizador de consulta detecta consultas em esquemas em estrela e cria planos de consulta eficientes para eles. Um método que o otimizador pode usar para gerar um plano eficiente é a filtragem de bitmap. Um filtro de bitmap usa uma representação compacta de um conjunto de valores de uma tabela em uma parte da árvore de operador de uma segunda tabela em outra parte da árvore. Essencialmente, o filtro executa uma redução de semijunção; quer dizer, só as filas na segunda tabela qualificadas para a junção à primeira tabela são processadas.

No SQL Server 2008, a filtragem de bitmap pode ser introduzida no plano de consulta depois da otimização, como no SQL Server 2005, ou pode ser introduzida dinamicamente pelo otimizador de consulta durante a geração do plano de consulta. Quando o filtro é introduzido dinamicamente, ele é chamado de filtro otimizado de bitmap. A filtragem otimizada de bitmap pode melhorar significativamente o desempenho das consultas de data warehouse que usam esquemas em estrela, removendo no início as linhas não qualificadas da tabela de fatos no plano de consulta. Sem a filtragem otimizada de bitmap, todas as linhas na tabela de fatos são processadas por alguma parte da árvore de operador antes da operação de junção com as remoções nas tabelas de dimensão das linhas não qualificadas. Quando a filtragem otimizada de bitmap for aplicada, as linhas não qualificadas na tabela de fatos serão eliminadas imediatamente.

A filtragem de bitmap otimizada está disponível apenas nas edições Enterprise, Developer e Evaluation do SQL Server.

Compreendendo a filtragem de bitmap

O filtro de bitmap é comparativamente melhor do que o índice de bitmap. Um índice de bitmap é uma forma alternativa de representação de listas de ID de linha (RID) em um índice de lista de valores que usa um ou mais vetores de bit que indicam qual linha em uma tabela contém certo valor de coluna. Ambos podem ser eficazes na remoção de linhas desnecessárias do processamento de resultado; contudo, há diferenças importantes entre um filtro de bitmap e um índice de bitmap. Primeiro, os filtros de bitmap são estruturas em memórias, eliminando assim qualquer sobrecarga de manutenção do índice devido a operações de linguagem de manipulação de dados (DML) realizadas na tabela subjacente. Além disso, os filtros de bitmap são muito pequenos e, ao contrário dos índices existentes em disco, que normalmente dependem do tamanho da tabela em que são construídos, podem ser criados filtros de bitmap dinamicamente com impacto mínimo no tempo de processamento de consulta.

Comparando filtragem de bitmap com filtragem otimizada de bitmap

A filtragem de bitmap e a filtragem otimizada de bitmap são implantadas no plano de consulta usando o operador de plano de execução bitmap. A filtragem de bitmap só é aplicada em planos de consulta paralelos em que junções de hash ou de mesclagem são usadas. A filtragem otimizada de bitmap só é aplicável em planos de consulta paralelos em que junções de hash são usadas. Em ambos os casos, o filtro de bitmap é criado no lado da entrada de construção (a tabela de dimensão) de uma junção de hash; contudo, a filtragem de fato é normalmente executada no operador Parallelism, que está no lado de entrada de investigação (a tabela de fato) da junção de hash. Quando a junção for baseada em uma coluna de inteiro, o filtro pode ser se aplicado diretamente à tabela inicial ou operação de varredura de índice em vez do operador Parallelism. Essa técnica é chamada otimização em linha.

Quando a filtragem de bitmap é introduzida no plano de consulta depois da otimização, o tempo de compilação de consulta é reduzido; no entanto, os planos de consulta que o otimizador pode considerar são limitados, e a cardinalidade e as estimativas de custo não são levadas em conta.

Filtros otimizados de bitmap têm as seguintes vantagens:

  • Suporte à filtragem de várias tabelas de dimensão.

  • Vários filtros podem ser se aplicados a um único operador.

  • Filtros otimizados de bitmap podem ser aplicados a mais tipos de operador. Esses incluem operadores de troca como os operadores Distribute Streams e Repartition Streams, operadores de varredura de índice ou tabela, e operadores de filtro.

  • A filtragem é aplicável a instruções SELECT e os operadores somente leitura são usados nas instruções INSERT, UPDATE, DELETE e MERGE.

  • A filtragem é aplicável à criação de exibições indexadas nos operadores usados para popular o índice.

  • O otimizador usa cardinalidade e estimativas de custo para determinar se a filtragem otimizada de bitmap é apropriada.

  • O otimizador pode considerar mais planos.

Como a filtragem otimizada de bitmap é implementada

Um filtro de bitmap só será útil se for seletivo. O otimizador de consulta determina quando um filtro otimizado de bitmap é seletivo o bastante para ser útil e para quais operadores o filtro é aplicado. O otimizador coloca os filtros otimizados de bitmap em todas as ramificações de uma junção em estrela e usa regras de custos para determinar se o plano oferece o menor custo de execução estimado. Quando o filtro otimizado de bitmap for não seletivo, a estimativa de custo será normalmente muito alta e o plano será descartado. Ao considerar onde colocar filtros otimizados de bitmap no plano, o otimizador procura variantes de junção de hash como uma pilha de junções de hash na profundidade correta. As junções com tabelas de dimensão são implementadas para executar primeiro a junção mais seletiva.

O operador em que o filtro otimizado de bitmap é aplicado contém um predicado de bitmap na forma de PROBE ([Opt_Bitmap1001], \{[column_name] \} [, 'IN ROW']). O predicado de bitmap faz o relato das seguintes informações:

  • O nome de bitmap que corresponde ao nome introduzido no operador Bitmap. O prefixo 'Opt_' indica que um filtro otimizado de bitmap é usado.

  • A coluna fez a investigação. Esse é o ponto do qual os dados filtrados passam pela árvore.

  • Se a investigação de bitmap usa otimização em linha. Quando usa, a investigação de bitmap é chamada com o parâmetro IN ROW. Caso contrário, esse parâmetro está faltando.

Exemplo

O exemplo a seguir representa uma consulta em relação a um esquema em estrela simples. As duas tabelas de dimensão DimProduct e DimCustomer são associadas à tabela de fatos FactInternetSales que usa uma junção de chave primária para chave estrangeira em uma única coluna de inteiro.

USE AdventureWorksDW2008R2;
GO
SELECT * 
FROM dbo.FactInternetSales AS F
INNER JOIN dbo.DimProduct AS D1 ON F.ProductKey = D1.ProductKey
INNER JOIN dbo.DimCustomer AS D2 ON F.CustomerKey = D2.CustomerKey
WHERE D1.StandardCost <= 30 AND D2.YearlyIncome <= 50000;

A ilustração a seguir mostra o plano de execução dessa consulta como pode aparecer no SQL Server 2005. Nos pontos marcados 1A, as tabelas de dimensão foram verificadas e as informações necessárias para filtrar as linhas não qualificadas da tabela de fatos (1B) são conhecidas. Porém, as propriedades do operador Table Scan mostram que nenhum predicado é usado para limitar as linhas retornadas da tabela de fatos.

Plano de consulta SQL Server sem filtros de bitmap.

Por outro lado, a ilustração a seguir mostra o plano de execução para a mesma consulta como pode aparecer no SQL Server 2008. Os operadores otimizados de bitmap são usados nas subárvores de ambas as tabelas de dimensão. As propriedades do operador table scan mostram que os filtros (investigações de bitmap) dessas subárvores são aplicados diretamente à árvore da tabela de fatos para limitar as linhas retornadas da tabela de fatos antes da primeira operação de junção.

Plano de consulta SQL Server com filtros de bitmap.

Requisitos de filtragem otimizada de bitmap

A filtragem otimizada de bitmap tem os seguintes requisitos:

  • As tabelas de fatos costumam ter pelo menos 100 páginas. O otimizador considera que tabelas menores são tabelas de dimensão.

  • Só junções internas entre uma tabela de fatos e uma tabela de dimensão são consideradas.

  • O predicado de junção entre a tabela de fatos e a tabela de dimensão deve ser uma única junção de coluna, mas não precisa ser uma relação de chave primária para chave estrangeira. Uma coluna baseada em inteiro é preferida.

  • As junções com dimensões só são consideradas quando as cardinalidades de entrada de dimensão são menores que a cardinalidade de entrada da tabela de fatos.