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 / 176627
Accepted
boot4life
boot4life
Asked: 2017-06-20 02:41:40 +0800 CST2017-06-20 02:41:40 +0800 CST 2017-06-20 02:41:40 +0800 CST

O operador de junção de hash sempre puxa do lado da compilação?

  • 772

Observando a execução de consultas com estatísticas de consulta ao vivo, notei que parece que o SQL Server está construindo preguiçosamente uma tabela de hash a partir da entrada de compilação de uma junção de hash.

Esta é uma diferença significativa no caso de 0 linhas de sondagem. Ele potencialmente salva toda a árvore do lado da compilação.

Eu sempre pensei que um hash funcionasse assim:

  1. Crie uma tabela de hash do lado da compilação.
  2. Combine todas as linhas do probe com ele.

Mas é o seguinte?

  1. Puxe a primeira linha de sonda.
  2. Conclua a operação se nenhuma linha estiver disponível (curto-circuito).
  3. Combine todas as linhas do probe com ele.

Não tenho certeza de como testar conclusivamente de que maneira é. Não tenho certeza se a saída das Estatísticas de consulta ao vivo pode ser confiável dessa maneira. Alguém sabe como isto funciona?

sql-server sql-server-2014
  • 1 1 respostas
  • 245 Views

1 respostas

  • Voted
  1. Best Answer
    Geoff Patterson
    2017-06-20T06:00:30+08:002017-06-20T06:00:30+08:00

    Se você postar o plano de consulta real para sua consulta específica, poderemos comentar sobre isso mais diretamente.

    Mas, em geral, acredito (e sempre observei) que o operador hash join sempre é executado como você esperava:

    1. Crie uma tabela de hash do lado da compilação.
    2. Combine todas as linhas do probe com ele.

    Isso geralmente faz sentido, pois o SQL Server colocará o conjunto de linhas menor (estimado) no lado de compilação da junção. Espera-se que o lado do probe seja maior que o lado da compilação (e, portanto, contenha pelo menos algumas linhas).

    Além disso, o SQL Server tem uma potencial otimização de bitmap que pode ser aplicada ao lado de investigação de uma junção de hash em alguns casos, mas essa otimização requer que o lado de compilação seja processado primeiro.

    Um exemplo

    Para uma consulta simples em que forçamos um lado de compilação grande da junção de hash e um lado de teste vazio, o plano de execução real mostra que todas as linhas são processadas no lado de compilação da junção.

    -- Fully processes the build side of the hash join
    SELECT SUM(b.number*p.number) AS meaningless
    FROM (
        SELECT 1.0 * v1.number * v2.number AS number
        FROM master..spt_values v1
        CROSS JOIN master..spt_values v2
    ) b
    INNER HASH JOIN (
        SELECT v3.number
        FROM master..spt_values v3
        WHERE number < -100000
    ) p
        ON p.number = b.number
    

    insira a descrição da imagem aqui

    O lado de construção pode ser ignorado?

    Há pelo menos um exemplo em que o lado de construção da junção de hash pode ser ignorado: Em alguns casos, a junção inteira pode ser eliminada. Por exemplo, aqui o SQL Server é capaz de provar antes da execução que o lado do probe terá 0 linhas. O plano de consulta final é, portanto, uma varredura constante e não há junção de hash.

    -- No hash join at all; the query optimizer realizes no rows are guaranteed
    SELECT SUM(b.number*p.number) AS meaningless
    FROM (
        SELECT 1.0 * v1.number * v2.number AS number
        FROM master..spt_values v1
        CROSS JOIN master..spt_values v2
    ) b
    INNER HASH JOIN (
        SELECT v3.number
        FROM master..spt_values v3
        WHERE 0=1
    ) p
        ON p.number = b.number
    

    E o modo de lote?

    Com base em um teste rápido, parece que o operador de junção de hash do modo de lote também processará totalmente o lado de compilação da junção de hash.

    -- The batch mode hash join also fully processes the build side
    -- even if there are 0 rows on the probe side
    SELECT number
    INTO #spt_values
    FROM master..spt_values
    GO
    CREATE CLUSTERED COLUMNSTORE INDEX CCI_#spt_values ON #spt_values
    GO
    SELECT SUM(b.number*p.number) AS meaningless
    FROM (
        SELECT 1.0 * v1.number * v2.number AS number
        FROM #spt_values v1
        CROSS JOIN #spt_values v2
    ) b
    INNER HASH JOIN (
        SELECT v3.number
        FROM #spt_values v3
        WHERE number < -100000
    ) p
        ON p.number = b.number
    GO
    
    • 3

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