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 / 185551
Accepted
Paul White
Paul White
Asked: 2017-09-11 12:12:10 +0800 CST2017-09-11 12:12:10 +0800 CST 2017-09-11 12:12:10 +0800 CST

Atualizações de índice exclusivo e contadores de modificação de linha de estatísticas

  • 772

Dada a tabela a seguir, índice clusterizado exclusivo e estatísticas:

CREATE TABLE dbo.Banana
(
    pk integer NOT NULL, 
    c1 char(1) NOT NULL, 
    c2 char(1) NOT NULL
);

CREATE UNIQUE CLUSTERED INDEX pk ON dbo.Banana (pk);

CREATE STATISTICS c1 ON dbo.Banana (c1);
CREATE STATISTICS c2 ON dbo.Banana (c2);

INSERT dbo.Banana 
    (pk, c1, c2) 
VALUES 
    (1, 'A', 'W'), 
    (2, 'B', 'X'), 
    (3, 'C', 'Y'), 
    (4, 'D', 'Z');

-- Populate statistics
UPDATE STATISTICS dbo.Banana;

Dados de exemplo

Os contadores de modificação de linha de estatísticas obviamente mostram zero antes de qualquer atualização:

-- Show statistics modification counters
SELECT
    stats_name = S.[name], 
    DDSP.stats_id,
    DDSP.[rows],
    DDSP.modification_counter
FROM sys.stats AS S
CROSS APPLY sys.dm_db_stats_properties(S.object_id, S.stats_id) AS DDSP
WHERE
    S.[object_id] = OBJECT_ID(N'dbo.Banana', N'U');

Contadores de modificação zero

Incrementando cada pkvalor de coluna em um para cada linha:

-- Increment pk in every row
UPDATE dbo.Banana 
SET pk += 1;

Usa o plano de execução:

Plano de execução Split Sort Recolher

Ele produz os seguintes contadores de modificação de estatísticas:

Contadores de modificação pós-atualização

Perguntas

  1. O que os operadores Dividir, Classificar e Recolher fazem?
  2. Por que as pkestatísticas mostram 2 modificações, mas c1mostram c25?
sql-server update
  • 1 1 respostas
  • 802 Views

1 respostas

  • Voted
  1. Best Answer
    Paul White
    2017-09-11T12:12:10+08:002017-09-11T12:12:10+08:00

    O SQL Server sempre usa a combinação de operadores Dividir, Classificar e Recolher ao manter um índice exclusivo como parte de uma atualização que afeta (ou pode afetar) mais de uma linha.

    Trabalhando com o exemplo da pergunta, poderíamos escrever a atualização como uma atualização de linha única separada para cada uma das quatro linhas presentes:

    -- Per row updates
    UPDATE dbo.Banana SET pk = 2 WHERE pk = 1;
    UPDATE dbo.Banana SET pk = 3 WHERE pk = 2;
    UPDATE dbo.Banana SET pk = 4 WHERE pk = 3;
    UPDATE dbo.Banana SET pk = 5 WHERE pk = 4;
    

    O problema é que a primeira instrução falharia, pois muda pkde 1 para 2 e já existe uma linha onde pk= 2. O mecanismo de armazenamento do SQL Server exige que os índices exclusivos permaneçam exclusivos em todas as etapas do processamento, mesmo dentro de uma única instrução . Este é o problema resolvido por Dividir, Classificar e Recolher.

    DividirDividir

    A primeira etapa é dividir cada instrução de atualização em uma exclusão seguida por uma inserção:

    DELETE dbo.Banana WHERE pk = 1;
    INSERT dbo.Banana (pk, c1, c2) VALUES (2, 'A', 'W');
    
    DELETE dbo.Banana WHERE pk = 2;
    INSERT dbo.Banana (pk, c1, c2) VALUES (3, 'B', 'X');
    
    DELETE dbo.Banana WHERE pk = 3;
    INSERT dbo.Banana (pk, c1, c2) VALUES (4, 'C', 'Y');
    
    DELETE dbo.Banana WHERE pk = 4;
    INSERT dbo.Banana (pk, c1, c2) VALUES (5, 'D', 'Z');
    

    O operador Split adiciona uma coluna de código de ação ao fluxo (aqui rotulado como Act1007):

    Propriedades de divisão

    O código de ação é 1 para uma atualização, 3 para uma exclusão e 4 para uma inserção.

    OrdenarOrdenar

    As instruções de divisão acima ainda produziriam uma violação de chave única transitória falsa, portanto, a próxima etapa é classificar as instruções pelas chaves do índice exclusivo que está sendo atualizado ( pkneste caso) e, em seguida, pelo código de ação. Para este exemplo, isso significa simplesmente que as exclusões (3) na mesma chave são ordenadas antes das inserções (4). A ordem resultante é:

    -- Sort (pk, action)
    DELETE dbo.Banana WHERE pk = 1;
    DELETE dbo.Banana WHERE pk = 2;
    INSERT dbo.Banana (pk, c1, c2) VALUES (2, 'A', 'W');
    DELETE dbo.Banana WHERE pk = 3;
    INSERT dbo.Banana (pk, c1, c2) VALUES (3, 'B', 'X');
    DELETE dbo.Banana WHERE pk = 4;
    INSERT dbo.Banana (pk, c1, c2) VALUES (4, 'C', 'Y');
    INSERT dbo.Banana (pk, c1, c2) VALUES (5, 'D', 'Z');
    

    Classificar propriedades

    ColapsoColapso

    O estágio anterior é suficiente para garantir a prevenção de falsas violações de exclusividade em todos os casos. Como uma otimização, Collapse combina exclusões e inserções adjacentes no mesmo valor de chave em uma atualização:

    -- Collapse (pk)
    DELETE dbo.Banana WHERE pk = 1;
    UPDATE dbo.Banana SET c1 = 'A', c2 = 'W' WHERE pk = 2;
    UPDATE dbo.Banana SET c1 = 'B', c2 = 'X' WHERE pk = 3;
    UPDATE dbo.Banana SET c1 = 'C', c2 = 'Y' WHERE pk = 4;
    INSERT dbo.Banana (pk, c1, c2) VALUES (5, 'D', 'Z');
    

    Os pares delete/insert para pkos valores 2, 3 e 4 foram combinados em uma atualização, deixando uma única exclusão em pk= 1 e uma inserção para pk= 5.

    O operador Collapse agrupa as linhas pelas colunas-chave e atualiza o código de ação para refletir o resultado do colapso:

    Recolher propriedades

    Atualização do índice clusterizadoAtualização de índice clusterizado

    Este operador é rotulado como Update, mas é capaz de inserções, atualizações e exclusões. Qual ação é executada pela atualização de índice clusterizado por linha é determinada pelo valor do código de ação nessa linha. O operador tem uma propriedade Action para refletir este modo de operação:

    Propriedade de ação de atualização de índice clusterizado


    Contadores de modificação de linha

    Observe que as três atualizações acima não modificam a(s) chave(s) do índice exclusivo que está sendo mantido. Na verdade, transformamos as atualizações das colunas- chave no índice em atualizações das colunas não-chave ( c1e c2), além de uma exclusão e uma inserção. Nem uma exclusão nem uma inserção podem causar uma violação de chave exclusiva falsa.

    Uma inserção ou exclusão afeta cada coluna na linha, portanto, as estatísticas associadas a cada coluna terão seus contadores de modificação incrementados. Para atualização(ões), apenas as estatísticas com qualquer uma das colunas atualizadas como a coluna principal têm seus contadores de modificação incrementados (mesmo que o valor não seja alterado).

    Os contadores de modificação de linha de estatísticas, portanto, mostram 2 alterações para pk, e 5 para c1e c2:

    -- Collapse (pk)
    DELETE dbo.Banana WHERE pk = 1;                         -- All columns modified
    UPDATE dbo.Banana SET c1 = 'A', c2 = 'W' WHERE pk = 2;  -- c1 and c2 modified
    UPDATE dbo.Banana SET c1 = 'B', c2 = 'X' WHERE pk = 3;  -- c1 and c2 modified
    UPDATE dbo.Banana SET c1 = 'C', c2 = 'Y' WHERE pk = 4;  -- c1 and c2 modified
    INSERT dbo.Banana (pk, c1, c2) VALUES (5, 'D', 'Z');    -- All columns modified
    

    Nota: Apenas as alterações aplicadas ao objeto base (heap ou índice clusterizado) afetam os contadores de modificação de linha de estatísticas. Índices não clusterizados são estruturas secundárias, refletindo as alterações já feitas no objeto base. Eles não afetam os contadores de modificação de linha de estatísticas.

    Se um objeto tiver vários índices exclusivos, uma combinação separada de Dividir, Classificar e Recolher é usada para organizar as atualizações de cada um. O SQL Server otimiza esse caso para índices não clusterizados salvando o resultado da divisão em um spool de tabela ansioso e, em seguida, reproduzindo esse conjunto para cada índice exclusivo (que terá suas próprias chaves de classificação por índice + código de ação e recolhimento).

    Efeito nas atualizações de estatísticas

    As atualizações automáticas de estatísticas (se habilitadas) ocorrem quando o otimizador de consulta precisa de informações estatísticas e percebe que as estatísticas existentes estão desatualizadas (ou inválidas devido a uma alteração de esquema). As estatísticas são consideradas desatualizadas quando o número de modificações registradas excede um limite.

    O arranjo Dividir/Classificar/Recolher resulta na gravação de diferentes modificações de linha do que seria esperado. Isso, por sua vez, significa que uma atualização de estatísticas pode ser acionada mais cedo ou mais tarde do que seria o caso de outra forma.

    No exemplo acima, as modificações de linha para a coluna-chave aumentam em 2 (a alteração líquida) em vez de 4 (uma para cada linha da tabela afetada) ou 5 (uma para cada exclusão/atualização/inserção produzida pelo Collapse).

    Além disso, as colunas não-chave que não foram alteradas logicamente pela consulta original acumulam modificações de linha, que podem numerar até o dobro das linhas da tabela atualizadas (uma para cada exclusão e uma para cada inserção).


    O número de alterações registradas depende do grau de sobreposição entre os valores de coluna de chave antigos e novos (e, portanto, o grau em que as exclusões e inserções separadas podem ser recolhidas). Redefinindo a tabela entre cada execução, as consultas a seguir demonstram o efeito nos contadores de modificação de linha com diferentes sobreposições:

    UPDATE dbo.Banana SET pk = pk + 0; -- Full overlap
    

    pk = pk + 0

    UPDATE dbo.Banana SET pk = pk + 1;
    

    pk = pk + 1

    UPDATE dbo.Banana SET pk = pk + 2;
    

    pk = pk + 2

    UPDATE dbo.Banana SET pk = pk + 3;
    

    pk = pk + 3

    UPDATE dbo.Banana SET pk = pk + 4; -- No overlap
    

    pk = pk + 4

    • 16

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