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 / 186420
Accepted
Peter
Peter
Asked: 2017-09-21 03:52:54 +0800 CST2017-09-21 03:52:54 +0800 CST 2017-09-21 03:52:54 +0800 CST

Reconstrução de índice offline em uma tabela particionada

  • 772

Se eu particionar uma tabela com ntext, textou tipos de imagedados e reconstruir um índice em uma única partição com online = off, isso bloqueará a tabela inteira ou apenas a partição em questão?

sql-server sql-server-2016
  • 1 1 respostas
  • 1141 Views

1 respostas

  • Voted
  1. Best Answer
    Erik Darling
    2017-10-01T07:26:05+08:002017-10-01T07:26:05+08:00

    Eu tive algum tempo para ver isso, e como eu já tinha alguns dos scripts de demonstração escritos, foi muito fácil verificar o resto. Vamos fazer a configuração, então veja os resultados. Isso criará a tabela e o índice particionados necessários.

    CREATE PARTITION FUNCTION YourMom ( INT )
        AS RANGE LEFT FOR VALUES ( 1000000, 2000000, 3000000, 4000000, 5000000 );
    
    CREATE PARTITION SCHEME YourDad
        AS PARTITION YourMom
        ALL TO ( [PRIMARY] );
    
    CREATE TABLE dbo.YourAuntDebbie
    (
        Id INT,
        StopUsingDeprecatedDataTypes NTEXT
    ) ON YourDad (Id);
    
    
    DECLARE @counter INT = 1;
    WHILE @counter < 6
        BEGIN
    
            RAISERROR('Run number: %d', 0, 1, @counter) WITH NOWAIT;
    
            INSERT dbo.YourAuntDebbie WITH ( TABLOCK ) ( Id, StopUsingDeprecatedDataTypes )
            SELECT TOP 1000000 x.n + CASE WHEN @counter = 1 THEN 0
                                          WHEN @counter = 2 THEN 1000000 
                                          WHEN @counter = 3 THEN 2000000 
                                          WHEN @counter = 4 THEN 3000000 
                                          WHEN @counter = 5 THEN 4000000 
                                          ELSE 0 
                                          END, 
                               REPLICATE(N'A', x.n % 10000)
            FROM   (   SELECT ROW_NUMBER() OVER ( ORDER BY @@ROWCOUNT ) AS n
                       FROM   sys.messages AS m
                       CROSS JOIN sys.messages AS m2 ) AS x;
    
            SET @counter += 1;
    
        END;
    
    CREATE CLUSTERED INDEX ix_whatever
        ON dbo.YourAuntDebbie ( Id ) ON YourDad(Id);
    

    Isso me dá 5 partições com 1 milhão de linhas e uma partição vazia.

    SELECT OBJECT_NAME(p.object_id) AS table_name, p.partition_number, p.rows
    FROM   sys.partitions AS p
    WHERE  p.object_id = OBJECT_ID('dbo.YourAuntDebbie');
    

    Mesa de fantasia:

    +----------------+------------------+---------+
    |   table_name   | partition_number |  rows   |
    +----------------+------------------+---------+
    | YourAuntDebbie |                1 | 1000000 |
    | YourAuntDebbie |                2 | 1000000 |
    | YourAuntDebbie |                3 | 1000000 |
    | YourAuntDebbie |                4 | 1000000 |
    | YourAuntDebbie |                5 | 1000000 |
    | YourAuntDebbie |                6 |       0 |
    +----------------+------------------+---------+
    

    Aqui está a sessão XE que estou usando para ver quais bloqueios as recompilações de índice precisam:

    CREATE EVENT SESSION Locks
        ON SERVER
        ADD EVENT sqlserver.lock_acquired
        ( SET collect_resource_description = ( 1 )
         ACTION ( sqlserver.sql_text )
         WHERE (   sqlserver.equal_i_sql_unicode_string(sqlserver.database_name, N'Crap')
                   AND package0.equal_uint64(sqlserver.session_id, ( 61 )))),
        ADD EVENT sqlserver.lock_released
        ( SET collect_resource_description = ( 1 )
         ACTION ( sqlserver.sql_text )
         WHERE (   sqlserver.database_name = N'Crap'
                   AND sqlserver.session_id = ( 61 )))
        ADD TARGET package0.event_file
        ( SET filename = N'c:\temp\Locks' )
        WITH ( MAX_MEMORY = 4096KB,
               EVENT_RETENTION_MODE = ALLOW_SINGLE_EVENT_LOSS,
               MAX_DISPATCH_LATENCY = 30 SECONDS,
               MAX_EVENT_SIZE = 0KB,
               MEMORY_PARTITION_MODE = NONE,
               TRACK_CAUSALITY = ON,
               STARTUP_STATE = OFF );
    GO
    

    Com isso no lugar, posso reconstruir minhas partições e, em seguida, cavar no XE.

    ALTER EVENT SESSION Locks ON SERVER STATE = START;
    
    ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 1 WITH (ONLINE = OFF);
    GO 
    
    ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 2 WITH (ONLINE = OFF);
    GO 
    
    ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 3 WITH (ONLINE = OFF);
    GO 
    
    ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 4 WITH (ONLINE = OFF);
    GO 
    
    ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 5 WITH (ONLINE = OFF); 
    GO 
    
    ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 6 WITH (ONLINE = OFF);
    GO 
    
    ALTER EVENT SESSION Locks ON SERVER STATE = STOP;
    

    Agora, vou colocar o evento XE triturando as coisas no final, porque é muito feio, e não há razão para fazer todo mundo assistir a isso para ver os resultados. Vou usar os resultados da primeira partição como exemplo, mas eles são praticamente idênticos em todas as 6 partições, mesmo na vazia.

    Estou limitando os resultados da atualização apenas aos bloqueios de nível de objeto. Estes são os únicos com os quais nos preocupamos.

       +---------------+-------------------------+----------------+--------------+-------+------------------+--------+
    |   EventName   |        EventDate        |   ObjectName   | ResourceType | Mode  | PARTITIONREBUILT | Events |
    +---------------+-------------------------+----------------+--------------+-------+------------------+--------+
    | lock_acquired | 2017-10-03 13:21:14.554 | YourAuntDebbie | OBJECT       | SCH_M | PARTITION = 1    |      1 |
    | lock_acquired | 2017-10-03 13:21:14.554 | YourAuntDebbie | OBJECT       | SCH_S | PARTITION = 1    |      1 |
    | lock_released | 2017-10-03 13:21:14.554 | YourAuntDebbie | OBJECT       | SCH_S | PARTITION = 1    |      1 |
    | lock_acquired | 2017-10-03 13:21:14.603 | YourAuntDebbie | OBJECT       | S     | PARTITION = 1    |      6 |
    | lock_acquired | 2017-10-03 13:21:14.603 | YourAuntDebbie | OBJECT       | SCH_S | PARTITION = 1    |     30 |
    | lock_released | 2017-10-03 13:21:14.603 | YourAuntDebbie | OBJECT       | SCH_S | PARTITION = 1    |     24 |
    | lock_released | 2017-10-03 13:21:14.867 | YourAuntDebbie | OBJECT       | SCH_M | PARTITION = 1    |      1 |
    +---------------+-------------------------+----------------+--------------+-------+------------------+--------+
    

    Pelo que posso dizer, para cada partição , um SCH-Mbloqueio é retirado no início da reconstrução do índice e liberado no final ON THE TABLE .

    Por exemplo, se eu executar uma reconstrução de partição única em uma transação:

    BEGIN TRAN
    
    ALTER INDEX ix_whatever ON dbo.YourAuntDebbie REBUILD PARTITION = 1 WITH (ONLINE = OFF);
    
    --ROLLBACK
    

    E então em outra janela do SSMS:

    SELECT *
    FROM dbo.YourAuntDebbie AS yad
    WHERE yad.Id = 6000000
    AND 1 = (SELECT 1)
    

    O select fica bloqueado até eu matar a reconstrução. Quando termina, o plano de consulta mostra a eliminação da partição ocorrendo , portanto, apenas a partição 1 sendo reconstruída parece afetar toda a tabela.

    NOZES

    Espero que isto ajude!

    Agora, aqui está o terrível código de destruição da sessão XE:

        CREATE TABLE #Locks
           (
             ID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY CLUSTERED,
             WaitsXML XML 
           );
    
    INSERT  #Locks
            ( WaitsXML )
    SELECT    CONVERT(XML, event_data) AS TargetData
    FROM      sys.fn_xe_file_target_read_file( 'c:\temp\Locks*.xel', NULL, NULL, NULL);
    
    WITH locks
    AS ( SELECT l.WaitsXML.value('(/event/@name)[1]', 'VARCHAR(128)') AS EventName,
                l.WaitsXML.value('(/event/@timestamp)[1]', 'DATETIME2(3)') AS EventDate,
                l.WaitsXML.value('(event/data[@name="object_id"]/value)[1]', 'NUMERIC') AS ObjectId,
                l.WaitsXML.value('(event/data[@name="resource_type"]/text)[1]', 'VARCHAR(128)') AS ResourceType,
                l.WaitsXML.value('(event/data[@name="mode"]/text)[1]', 'VARCHAR(128)') AS Mode,
                l.WaitsXML.value('(event/action[@name="sql_text"]/value)[1]', 'VARCHAR(128)') AS SQLText,
                l.WaitsXML
         FROM   #Locks AS l )
    SELECT   locks.EventName,
             locks.EventDate,
             ISNULL(OBJECT_NAME(locks.ObjectId), 'Unknown') AS ObjectName,
             locks.ResourceType,
             locks.Mode,
             SUBSTRING(
                 locks.SQLText,
                 CHARINDEX('PARTITION', locks.SQLText),
                 CHARINDEX('WITH', locks.SQLText, CHARINDEX('PARTITION', locks.SQLText))
                 - CHARINDEX('PARTITION', locks.SQLText)) AS PARTITIONREBUILT,
             COUNT(*) AS Events
    FROM     locks
    WHERE    OBJECT_NAME(locks.ObjectId) = 'YourAuntDebbie'
             --OR OBJECT_NAME(locks.ObjectId) IS NULL
    GROUP BY ISNULL(OBJECT_NAME(locks.ObjectId), 'Unknown'),
             SUBSTRING(
                 locks.SQLText,
                 CHARINDEX('PARTITION', locks.SQLText),
                 CHARINDEX('WITH', locks.SQLText, CHARINDEX('PARTITION', locks.SQLText))
                 - CHARINDEX('PARTITION', locks.SQLText)),
             locks.EventName,
             locks.EventDate,
             locks.ResourceType,
             locks.Mode
    ORDER BY locks.EventDate;
    
    • 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