AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 340540
Accepted
J. Mini
J. Mini
Asked: 2024-06-27 04:15:53 +0800 CST2024-06-27 04:15:53 +0800 CST 2024-06-27 04:15:53 +0800 CST

Por que adicionar um índice columnstore vazio às minhas tabelas faz com que os planos de execução ignorem os bitmaps de forma consistente?

  • 772

Problema

Estou usando uma caixa SQL Server 2019 Standard Edition. Dada a edição, os níveis de compatibilidade não devem ser relevantes (os recursos do modo batch dependente do nível não são permitidos no Standard). Nesta caixa, tenho experimentado o hack de adicionar um índice columnstore filtrado e não clusterizado vazio a uma tabela temporária antes de juntá-lo a outras tabelas, permitindo assim que as consultas com a referida junção usem o modo em lote, apesar de não usarem nenhum índice columnstore . Quando faço isso, tenho encontrado regularmente o seguinte comportamento nas consultas que anteriormente não usavam o modo em lote:

  • As partes dos planos de execução que agora usam o modo em lote são executadas muito mais rapidamente. Em particular, as funções de janela tornam-se incríveis em comparação com o que eram nos planos que não tinham peças em modo lote.
  • Os planos com peças em modo batch terão sempre um custo muito menor do que as consultas que não o fazem, mesmo que demorem mais para serem executadas.
  • Às vezes, o Gather Streams fica muito mais lento, mesmo que cada operador esteja sendo executado uniformemente em dois threads nos planos que possuem etapas no modo em lote.
  • Consultas que anteriormente construíam um bitmap em uma tabela para fazer uma varredura barata e depois fazer hash em outra tabela, passando pela sonda de hash do bitmap na varredura, tornam-se muito mais lentas. Em vez de um bitmap dentro de uma varredura de índice, eles têm um operador de filtro muito caro após a varredura.

Existe alguma explicação para a observação final da minha lista? Mais importante ainda, como posso evitar a introdução do modo em lote, removendo bitmaps excelentes? Esse ponto ousado é o que quero que seja respondido aqui. Se eu pudesse ter os bitmaps e os excelentes benefícios do modo em lote em outro lugar da consulta (por exemplo, nas funções da janela), minhas consultas seriam muito mais rápidas. Aceito que provavelmente poderia indexar melhor as tabelas, mas já estava satisfeito com as junções de hash originais.

Exemplo reproduzível

Erik Darling, com razão, solicitou que eu colasse o plano, mas pensei em fazer melhor e dar um exemplo reproduzível. O seguinte usa o banco de dados StackOverflow2010 . Você pode carregar isso em um contêiner docker, se desejar.

SET STATISTICS XML OFF;

USE StackOverflow2010;

DROP TABLE IF EXISTS #IDs;

SELECT TOP (10000)
  Id
INTO
  #IDs
FROM
  Comments;

ALTER TABLE #IDs ADD CONSTRAINT RowStorePK
PRIMARY KEY CLUSTERED (Id);

SET STATISTICS XML ON;
  
;WITH [NumberedPosts] AS
(
  SELECT
    PostID
    ,ROW_NUMBER() OVER (PARTITION BY PostID ORDER BY Score) RN
  FROM
    Comments
  WHERE
    PostID IN (SELECT Id FROM #IDs)
)
SELECT
  PostID
FROM
  NumberedPosts
WHERE
  RN = 1;

/*
  Hack to get batch mode for these queries despite 
  my real machine being on Standard Edition.
*/
CREATE NONCLUSTERED COLUMNSTORE INDEX ColStoreNonClust ON #IDs (ID)
WHERE ID = 1 AND ID = 2;

-- Same query again.

;WITH [NumberedPosts] AS
(
  SELECT
    PostID
    ,ROW_NUMBER() OVER (PARTITION BY PostID ORDER BY Score) RN
  FROM
    Comments
  WHERE
    PostID IN (SELECT Id FROM #IDs)
)
SELECT
  PostID
FROM
  NumberedPosts
WHERE
  RN = 1;

Este plano é anterior à criação do índice columnstore. Ele usa um bitmap. Este plano é posterior à criação do índice columnstore. Ele não usa um bitmap e é executado muito mais lentamente que a consulta que usa bitmap.

Já vi isso tantas vezes que me convenci de que é um padrão que deve ter alguma explicação geral ou etapas de prevenção.

sql-server
  • 1 1 respostas
  • 92 Views

1 respostas

  • Voted
  1. Best Answer
    Paul White
    2024-07-03T03:00:50+08:002024-07-03T03:00:50+08:00

    como posso evitar a introdução do modo em lote, removendo bitmaps excelentes?

    Resposta curta

    Você não pode. Você precisará atualizar da Standard Edition.

    Resposta longa

    Ambos podem ser chamados de bitmaps, mas os bitmaps de modo de linha são muito diferentes dos bitmaps de modo de lote .

    Os bitmaps do modo em lote são criados apenas por hash joins no modo em lote. Eles foram originalmente implementados para uso somente com varreduras de colunas em modo lote.

    Quando planos de modo misto (contendo operadores de modo de linha e de lote) foram adicionados, suporte específico foi incluído para avaliar a estrutura de bitmap de modo de lote diferente em um operador de filtro de modo de linha .

    Esse apoio é minimamente necessário para fazer as coisas funcionarem. Otimizações como empurrar o filtro para dentro da varredura como um predicado residual ('não sarg'), ou ainda mais profundamente no mecanismo de armazenamento, simplesmente não foram implementadas.

    Eles poderiam ter implementado essas otimizações, resultando no tipo de resultado que você está procurando. No caso, eles decidiram investir tempo e esforço na criação do Modo Lote no Rowstore (BMoR).

    O modo em lote no rowstore permite a execução em modo lote para cargas de trabalho analíticas sem exigir índices columnstore. Este recurso oferece suporte à execução em modo de lote e filtros de bitmap para heaps em disco e índices de árvore B. O modo em lote no rowstore permite suporte para todos os operadores habilitados para modo em lote existentes.

    Conforme brevemente observado na documentação acima (ênfase adicionada), o BMoR permite que o bitmap do modo em lote seja avaliado em uma varredura no modo em lote de um índice rowstore. Ele oferece muitos outros benefícios gerais além disso, é claro.

    Infelizmente, o BMoR é um recurso de desempenho premium e, portanto, não está disponível na Standard Edition.

    Se você usar uma junção hash no modo em lote no Padrão, você terá um bitmap preso em um Filtro (a menos que o destino seja columnstore e acessado no modo em lote).

    Se você usar uma junção hash no modo de linha, obterá um tipo diferente de bitmap que pode ser inserido profundamente no mecanismo de armazenamento (em circunstâncias limitadas).

    Você não pode ter o melhor dos dois mundos no Standard. Você pode ter uma junção de hash no modo em lote e um filtro travado ou uma junção de hash no modo de linha e um bitmap que pode ser empurrado para baixo.

    O nível de compatibilidade não é um fator, conforme mencionado na pergunta.

    Embargo

    Nenhuma das opções acima significa sugerir que você não pode ter o modo de lote em algumas partes do plano e o modo de linha em outras. É limitado ao ponto preciso sobre o comportamento dos bitmaps associados a uma junção hash.

    O otimizador geralmente é capaz de escolher um plano com hash join em modo de linha mais bitmap, ao mesmo tempo em que executa outros operadores como Sort ou Window Aggregate em modo de lote. Também é perfeitamente capaz de não fazer o que deseja em nenhum caso específico. Tudo está sujeito a estimativas de custos e heurísticas.

    Se você puder gerar a forma de plano desejada usando métodos suportados, poderá forçar esse plano usando o armazenamento de consultas ou guias de plano. Boa sorte com isso, em geral.

    Hash join em modo de linha com bitmap mais operações em modo de lote Tecnicamente possível, mas incomum

    No seu exemplo, é extremamente improvável que o otimizador escolha o modo em lote para os operadores desejados, ao mesmo tempo que escolhe o modo de linha para a junção de hash. O plano acima serve apenas para mostrar que é uma saída tecnicamente válida do otimizador. Ele não foi gerado usando técnicas suportadas.

    Bitmap com junção de mesclagem

    A seguinte consulta de demonstração ajustada produz o bitmap desejado com uma junção de mesclagem:

    -- Hack empty CS index present on #IDs
    WITH 
        NumberedPosts AS
        (
            SELECT
                C.PostId,
                rn = 
                    ROW_NUMBER() OVER (
                        PARTITION BY C.PostId
                        ORDER BY C.Score) 
            FROM dbo.Comments AS C
            WHERE
                PostID IN 
                (
                    SELECT 
                        Id + 0 - 0 
                    FROM #IDs
                )
        )
    SELECT
        NP.PostId
    FROM NumberedPosts AS NP
    WHERE
        NP.rn = 1
    OPTION 
    (
        MERGE JOIN
    );
    

    Mesclar junção com operadores de modo bitmap e em lote

    BMoR não é usado. Todos os operadores acima da junção de mesclagem estão no modo em lote. O filtro de modo de linha muito seletivo é empurrado para a varredura paralela do mecanismo de armazenamento de Comments .

    • 7

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve