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 / 345758
Accepted
SE1986
SE1986
Asked: 2025-03-17 22:47:29 +0800 CST2025-03-17 22:47:29 +0800 CST 2025-03-17 22:47:29 +0800 CST

Operador de atualização de índice agrupado executando leituras lógicas excessivas após alteração de consulta

  • 772

Se eu tiver a seguinte consulta no banco de dados Stack Overflow2010

UPDATE  dbo.Posts
SET     Title =
        CASE 
            WHEN CreationDate <= '2008-01-01T00:00:00'
            THEN 'A'
            ELSE 'B'
        END
FROM    dbo.Posts

A saída resumida STATISTICS IO está abaixo

Table 'Posts'. Scan count 1, logical reads 445699, physical reads 375822, page server reads 0, read-ahead reads 445521, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.

(1878895 rows affected)

e o plano de execução está aqui

Se eu criar uma tabela para armazenar o valor que desejo usar na minha comparação:

CREATE TABLE dbo.Canary
(
    TheDate DATETIME
)

INSERT INTO dbo.Canary VALUES ('2008-01-01T00:00:00')

e então se eu alterar a consulta da seguinte forma:

UPDATE  dbo.Posts
SET     Title =
        CASE 
            WHEN CreationDate <= Canary.TheDate
            THEN 'A'
            ELSE 'B'
        END
FROM    dbo.Posts
        CROSS JOIN dbo.Canary

A saída STATISTICS IO é

Table 'Canary'. Scan count 1, logical reads 1, physical reads 1, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'Posts'. Scan count 1, logical reads 16787757, physical reads 3127, page server reads 0, read-ahead reads 784795, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, page server reads 0, read-ahead reads 6291, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.

(1878895 rows affected)

e o plano de execução está aqui

Podemos ver que o número de leituras lógicas aumentou massivamente, de 445k para 16m. Levei algum tempo para encontrar no plano de execução onde está a fonte disso, mas eu o rastreei usando a propriedade Estatísticas de E/S reais / Leituras lógicas reais e posso ver que as leituras extras estão no operador de atualização de índice clusterizado, também posso ver que esse operador agora tem um valor para Número real de linhas para todas as execuções, enquanto o plano para a primeira consulta não tem.

O que está acontecendo aqui? O que está acontecendo na atualização do índice clusterizado que está causando o aumento nas leituras?

Acredito que a consulta deve usar uma variável se esse padrão de "valor em uma tabela de configuração" for usado. No entanto, esta é uma consulta de um aplicativo de fornecedor, então quero dar um feedback sobre o que está acontecendo como resultado da consulta ter sido escrita da maneira que foi.

sql-server
  • 1 1 respostas
  • 446 Views

1 respostas

  • Voted
  1. Best Answer
    Martin Smith
    2025-03-18T00:30:23+08:002025-03-18T00:30:23+08:00

    Ao adicionar o, CROSS JOIN dbo.Canaryvocê não obtém mais o benefício do compartilhamento de conjuntos de linhas e o UPDATEoperador precisa localizar cada linha a ser atualizada, em vez de apenas usar a posição da varredura na parte de leitura do plano.

    insira a descrição da imagem aqui

    Essa alteração na consulta pode significar que há muitas linhas no lado de leitura que precisam ser reduzidas a uma para que UPDATEum agregado de fluxo com o ANYagregado seja adicionado ao plano.

    Presumo que a adição do agregado de fluxo intermediário é o que impede o compartilhamento do conjunto de linhas neste caso.

    Se você remover o agregado (por exemplo, com o abaixo ou adicionando um índice exclusivo Canarye realizando uma busca exclusiva), o compartilhamento do conjunto de linhas acontece novamente.

    UPDATE  dbo.Posts
    SET     Title =
            CASE 
                WHEN CreationDate <= Canary.TheDate
                THEN 'A'
                ELSE 'B'
            END
    FROM    dbo.Posts
            CROSS JOIN (SELECT TOP 1 * FROM dbo.Canary) Canary
    

    Para ver em um ambiente de não produção se o plano de execução usa compartilhamento de conjunto de linhas, você pode usar um traceflag não documentado ( DBCC TRACEON (8666)) e observar as propriedades do UPDATEoperador no plano de execução.

    insira a descrição da imagem aqui

    ( Edição: Não tenho o banco de dados StackOverflow instalado, então criei uma Poststabela vazia para o acima. Não percebi que você havia postado planos de execução e veja que no seu caso o colapso de muitos para um é feito por um operador de classificação distinto intermediário. Imagino que a TOP 1abordagem deva se livrar disso também. Outro aspecto do seu plano de problema é que ele é paralelo. Se ele ainda permanecer paralelo, talvez seja necessário adicionar uma MAXDOP 1dica, pois isso também significará que as linhas não estão mais sendo transmitidas diretamente da varredura para a atualização, uma por uma, e impedirá o compartilhamento do conjunto de linhas.)

    • 13

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