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 / 239487
Accepted
Hannah Vernon
Hannah Vernon
Asked: 2019-05-31 11:25:40 +0800 CST2019-05-31 11:25:40 +0800 CST 2019-05-31 11:25:40 +0800 CST

Qual é o objetivo desta coluna Uniq1002 nesta verificação de índice?

  • 772

Faça a seguinte reprodução:

USE tempdb;

IF OBJECT_ID(N'dbo.t', N'U') IS NOT NULL
DROP TABLE dbo.t
GO
CREATE TABLE dbo.t
(
    id int NOT NULL 
        PRIMARY KEY 
        NONCLUSTERED 
        IDENTITY(1,1)
    , col1 datetime NOT NULL
    , col2 varchar(800) NOT NULL
    , col3 tinyint NULL
    , col4 sysname NULL
);

INSERT INTO dbo.t (
      col1
    , col2
    , col3
    , col4
    ) 
SELECT TOP(100000) 
      CONVERT(datetime, 
         DATEADD(DAY, CONVERT(int, CRYPT_GEN_RANDOM(1)), '2000-01-01 00:00:00'))
    , replicate('A', 800)
    , sc2.bitpos
    , CONVERT(sysname, CHAR(65 + CRYPT_GEN_RANDOM(1) % 26) 
        + CHAR(65 + CRYPT_GEN_RANDOM(1) % 26) 
        + CHAR(65 + CRYPT_GEN_RANDOM(1) % 26))
FROM sys.syscolumns sc
    CROSS JOIN sys.syscolumns sc2;

Aqui estou adicionando um índice clusterizado em um conjunto de colunas que não são exclusivas e um índice típico não clusterizado de coluna única:

CREATE CLUSTERED INDEX t_cx 
ON dbo.t (col1, col2, col3);

CREATE INDEX t_c1 ON dbo.t(col4); 

Essa consulta força o SQL Server a fazer uma pesquisa no índice clusterizado. Por favor, perdoe o uso da dica de índice, foi a maneira mais rápida de obter a reprodução:

SELECT id
    , col1
    , col2
    , col3
FROM dbo.t aad WITH (INDEX = t_c1)
WHERE col4 = N'JSB'
    AND col1 > N'2019-05-30 00:00:00';

O plano de consulta real mostra uma coluna inexistente na Lista de saída para a verificação de índice não clusterizado:

insira a descrição da imagem aqui

Aparentemente, isso representa o unificador usado no índice clusterizado não exclusivo. É esse o caso? Uma coluna com esse nome é sempre o unificador de índice clusterizado?

sql-server sql-server-2012
  • 2 2 respostas
  • 211 Views

2 respostas

  • Voted
  1. Best Answer
    Paul White
    2019-06-01T03:33:51+08:002019-06-01T03:33:51+08:00

    Aparentemente, isso representa o unificador usado no índice clusterizado não exclusivo. É esse o caso?

    Sim.

    Qual é o objetivo desta coluna Uniq1002 nesta verificação de índice?

    Cada linha no índice não clusterizado deve ser associada a exatamente uma linha na tabela base para que as Pesquisas de Marcador (RID ou Chave) funcionem corretamente. Este mapeamento é fornecido pelo "localizador de linha".

    Para tabelas de heap, o localizador de linha é o RID. Para tabelas de armazenamento de linhas agrupadas, é a chave de agrupamento (incluindo o unificador quando necessário).

    Para que a Pesquisa de Chave em seu plano funcione, ela deve ter acesso ao localizador de linha. Isso inclui o uniquifier , portanto, ele deve ser emitido pela varredura de índice não clusterizado.

    O unificador é armazenado na parte de comprimento variável da linha, de modo que só ocupa espaço quando necessário (ou seja, quando uma chave duplicada realmente existe).

    Uma coluna com esse nome é sempre o unificador de índice clusterizado?

    Sim. A coluna unificadora é sempre nomeada UniqXXXX. O localizador de linha associado às tabelas de heap é denominado BmkXXXX. O localizador de linha para uma tabela columnstore é denominado ColStoreLocXXXX.


    Observando o unificador

    É possível observar diretamente os valores do unificador nas versões do SQL Server que contêm um query_trace_column_valuesExtended Event funcional .

    Este evento não documentado e sem suporte está no canal Debug . Ele foi introduzido com o SQL Server 2016 e parou de funcionar em torno do CU11 do SQL Server 2017.

    Por exemplo:

    CREATE TABLE #T (c1 integer NULL INDEX ic1 CLUSTERED, c2 integer NULL INDEX ic2 UNIQUE, c3 integer NULL);
    GO
    INSERT #T
        (c1, c2, c3)
    VALUES 
        (100, 101, 0),
        (100, 102, 1),
        (100, 103, 2);
    GO
    DBCC TRACEON (2486);
    SET STATISTICS XML ON;
    SELECT T.* FROM #T AS T WITH (INDEX(ic2));
    SET STATISTICS XML OFF;
    DBCC TRACEOFF (2486);
    GO
    DROP TABLE #T;
    

    Tem o plano:

    Plano

    Ele produz uma saída de evento como a seguinte no SQL Server 2016:

    Saída do evento

    • 9
  2. Hannah Vernon
    2019-05-31T11:42:49+08:002019-05-31T11:42:49+08:00

    Para que o SQL Server crie um índice clusterizado não exclusivo , uma "coluna" oculta é adicionada à estrutura física do índice clusterizado. Essa coluna oculta é conhecida como uniqifier e, como o próprio nome indica, fornece um mecanismo para garantir que cada linha no índice clusterizado seja exclusiva.

    Quando você vê essa coluna aparecer em um plano de consulta, é um ótimo indicador de que as colunas de chave de clustering não foram definidas como exclusivas. Possivelmente isso ocorre porque a combinação de colunas é conhecida por não ser única. Também é possível que o designer da tabela simplesmente tenha esquecido de adicionar o UNIQUEqualificador à CREATE CLUSTERED INDEXinstrução.

    De fato, se recriarmos o repro acima com um índice clusterizado exclusivo, a Uniq1002coluna não aparecerá mais no plano de consulta:

    USE tempdb;
    
    IF OBJECT_ID(N'dbo.t', N'U') IS NOT NULL
    DROP TABLE dbo.t
    GO
    CREATE TABLE dbo.t
    (
        id int NOT NULL 
            PRIMARY KEY 
            NONCLUSTERED 
            IDENTITY(1,1)
        , col1 datetime NOT NULL
        , col2 varchar(800) NOT NULL
        , col3 int NULL
        , col4 sysname NULL
    );
    
    INSERT INTO dbo.t (
          col1
        , col2
        , col3
        , col4
        ) 
    SELECT TOP(100000) 
          CONVERT(datetime, DATEADD(DAY, CONVERT(int, CRYPT_GEN_RANDOM(1)), '2000-01-01 00:00:00'))
        , replicate('A', 800)
        , CONVERT(int, CRYPT_GEN_RANDOM(4))
        , CONVERT(sysname, CHAR(65 + CRYPT_GEN_RANDOM(1) % 26) 
            + CHAR(65 + CRYPT_GEN_RANDOM(1) % 26) 
            + CHAR(65 + CRYPT_GEN_RANDOM(1) % 26))
    FROM sys.syscolumns sc
        CROSS JOIN sys.syscolumns sc2;
    

    Aqui está o índice clusterizado UNIQUE:

    CREATE UNIQUE CLUSTERED INDEX t_cx 
    ON dbo.t (col1, col2, col3);
    
    CREATE INDEX t_c1 ON dbo.t(col4); 
    

    E a consulta:

    SELECT id
        , col1
        , col2
        , col3
    FROM dbo.t aad WITH (INDEX = t_c1)
    WHERE col4 = N'JSB'
        AND col1 > N'2019-05-30 00:00:00';
    

    O plano agora mostra isso para as colunas de saída de varredura de índice não clusterizado:

    insira a descrição da imagem aqui

    Quando um índice clusterizado não exclusivo é criado, o uniqifier é adicionado automaticamente. O uniqifier também é adicionado a todos os índices não agrupados, mesmo que você não possa "vê-lo" observando as propriedades do índice ou "criando scripts" do índice.

    O uniqifier é uma coluna de quatro bytes contendo um inteiro que é incrementado automaticamente nos bastidores para cada linha inserida na tabela. A primeira linha inserida não requer um unificador; apenas as linhas adicionadas após a primeira linha têm o uniqifier presente.

    • 2

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