zoukankan      html  css  js  c++  java
  • 4. 跟踪标记 (Trace Flag) 610 对索引组织表(IOT)最小化日志

    跟踪标记:610

    功能:

    • 用批量导入操作(Bulk Import Operations)加载数据时,对于索引组织表(即有聚集索引的表) 最小化日志;

     

    上图为simple/bulk-logged恢复模式下,最小化日志的几种操作,其中包含了批量导入操作,而批量导入操作的最小化日志有一些前提条件,概括如下:

    1. 目标表未用于复制;

    2. 目标表上指定了TABLOCK

    3. 目标表上的索引情况,这条规则最复杂,见下表:

    从表格可以看出:

    (1) 堆表的数据页一直可以最小化日志;

    (2) 聚集索引和非聚集索引,一直是完全记录日志的,除了在空表的情况下(即索引也是空的),第一个批次(batch)导入的数据可以最小化日志,从第二个批次(batch)起就不再是最小化日志,原因就是第一个批次(batch)结束后,就不再是空表了,跟踪标记610也正是因为这个而出现;

    用途:

    • 提升索引组织表(即有聚集索引的表)批量导入操作的性能;

    备注:

    (1) 从SQL Server 2008 开始,引入了跟踪标记610;

    (2) 从SQL Server 2016开始,跟踪标记610所具备的功能,已经被数据库引擎所默认,不需要再额外手动开启跟踪标记 (同样的,也就没有开关去关闭) ;

    测试:观察[Log Record Length]这列的变化和区别

    -- Set Recover model to SIMPLE/BULK_LOGGED
    ALTER DATABASE testing SET RECOVERY SIMPLE;
    
    /**************************START of CREATE TEST TABLES******************************/
    USE testing
    GO
    
    IF OBJECT_ID('SrcHeap') IS NOT NULL 
     DROP TABLE SrcHeap;
    
    IF OBJECT_ID('TarHeap') IS NOT NULL 
     DROP TABLE TarHeap;
    
    IF OBJECT_ID('TarTable') IS NOT NULL 
     DROP TABLE TarTable;
    
    CREATE TABLE SrcHeap (col1 INT ,col2 CHAR(4000),col3 CHAR(1000) ) ; 
    
    CREATE TABLE TarHeap( col1 INT ,col2 CHAR(4000),col3 CHAR(1000) ) ;
    
    CREATE TABLE TarTable (col1 INT ,col2 CHAR(4000),col3 CHAR(1000) ); 
    create clustered index IX_01 on TarTable(col1);
    
    --Insert row into source table
    WITH Nums (col)
    AS 
    (
     SELECT 1 col
     UNION ALL 
     SELECT col + 1 FROM Nums
     WHERE col+1 <= 10000
    )
    INSERT INTO SrcHeap(col1,col2,col3) 
     SELECT col,replicate('A',4000),replicate('B',1000) FROM Nums 
     OPTION (MAXRECURSION 10000)
    /**************************END of CREATE TEST TABLES******************************/
    
    /**************************START of HEAP testing******************************/
    --Insert rows to Target Table with (TABLOCK) Minimally logged
    INSERT INTO TarHeap WITH(TABLOCK)
     SELECT * FROM SrcHeap 
    
    -- Check Log Entries
    SELECT TOP 10 operation [MINIMALLY LOGGED OPERATION],context, [log record fixed length], [log record length], AllocUnitId, AllocUnitName
     FROM fn_dblog(null, null)
     WHERE allocunitname='dbo.TarHeap'
     ORDER BY [Log Record Length] DESC;
    --Note That [Log Record length] is small 
    
    --Insert rows to Target Table without (TABLOCK) fully logged
    INSERT INTO TarHeap 
     SELECT * FROM SrcHeap WITH(NOLOCK);
    
    -- Check Log Entries
    SELECT TOP 10 operation [FULLY LOGGED OPERATION],context, [log record fixed length], [log record length], AllocUnitId, AllocUnitName
     FROM fn_dblog(null, null)
     WHERE allocunitname='dbo.TarHeap'
     ORDER BY [Log Record Length] DESC;
    --Note That [Log Record length] is big 
    /**************************END of HEAP testing******************************/
    
    /**************************START of INDEXED TABLES testing WITHOUT 610******************************/
    --Insert rows to Target Table with clustered index and trace flag 610 off 
    --Fully logged from second batch
    
    --First Batch
    INSERT INTO TarTable  WITH(TABLOCK)
     SELECT * FROM SrcHeap WITH(NOLOCK);
    
    CHECKPOINT;
    --first batch with or without 610
    select * 
     FROM fn_dblog(null, null)
     WHERE allocunitname LIKE '%TarTable%' --4582 rows
      and operation = 'LOP_INSERT_ROWS'--0 rows
    
    --Second Batch
    INSERT INTO TarTable  WITH(TABLOCK)
     SELECT col1+10000,col2,col3 FROM SrcHeap WITH(NOLOCK);
    
    CHECKPOINT
    --from second batch without 610, tested twice
    SELECT * 
     FROM fn_dblog(null, null)
     WHERE allocunitname LIKE '%TarTable%' --114308 rows, 114293 rows
      and operation = 'LOP_INSERT_ROWS'--20090 rows, 20088 rows
      and (context  = 'LCX_CLUSTERED'   --10000 rows (actual rows)
           or 
           context = 'LCX_INDEX_INTERIOR' --44 rows (description)
          )
     ORDER BY [Log Record Length] DESC
    /**************************END of INDEXED TABLES testing WITHOUT 610******************************/
    
    CHECKPOINT;
    GO
    DBCC TRACEON(610);
    TRUNCATE TABLE TarTable;
    GO
    
    /**************************START of INDEXED TABLES testing WITH 610******************************/
    --Insert rows to Target Table with clustered index and trace flag 610 on 
    --Minimally logged for all batches
    --with 610 enables + with TABLOCK, the first bath logged less than second batch
    --with 610 enables + without TABLOCK, the first batch processes as same as begining with second batch
    INSERT INTO TarTable  --WITH(TABLOCK)
     SELECT * FROM SrcHeap WITH(NOLOCK);
    
    INSERT INTO TarTable  --WITH(TABLOCK)
     SELECT col1+10000,col2,col3 FROM SrcHeap WITH(NOLOCK);
    
    CHECKPOINT
    --from second batch with 610
    SELECT * 
     FROM fn_dblog(null, null)
     WHERE allocunitname LIKE '%TarTable%' --54995 rows
      and operation = 'LOP_INSERT_ROWS'--10090 rows
      and (context  = 'LCX_CLUSTERED'   --0 rows (autual rows)
           or 
           context = 'LCX_INDEX_INTERIOR' --44 rows (description)
          )
     ORDER BY [Log Record Length] DESC
    /**************************END of INDEXED TABLES testing WITH 610******************************/
    
    DBCC TRACEOFF(610)
    DBCC TRACESTATUS(-1)

    小结:

    (1) 条件允许情况下,批量导入操作还是跑在堆表上性能最佳;

    (2) 跟踪标记610被开启后,对于聚集索引,只有新分配的数据页才会最小化日志,数据插入已有数据页,仍然是fully logged,所以建表时还得考虑聚集索引键的选择;

    (3) 跟踪标记610被开启后,对于非聚集索引,并不一定可以最小化日志,这取决于查询优化器对执行计划的选择;

    (4) 跟踪标记610被开启后,对于堆表,仍然要指定TABLOCK;对于索引组织表,可不指定TABLOCK,也仍然可以最小化日志,每个批次(batch)最小化日志方式一致;

    参考:

    Operations That Can Be Minimally Logged

    https://technet.microsoft.com/en-us/library/ms191244(v=sql.105).aspx

    Prerequisites for Minimal Logging in Bulk Import

    https://technet.microsoft.com/en-us/library/ms190422(v=sql.105).aspx

    DBCC TRACEON - Trace Flags (Transact-SQL)

    https://docs.microsoft.com/en-us/sql/t-sql/database-console-commands/dbcc-traceon-trace-flags-transact-sql

    The Data Loading Performance Guide

    https://technet.microsoft.com/en-us/library/dd425070(v=sql.100).aspx

  • 相关阅读:
    MySql行锁等待时间
    日志工具类-Mapper静态调用
    MySql锁机制理解记录
    Flink之TableAPI和SQL(5):表的时间特性
    Flink之TableAPI和SQL(4):表的Sink实现
    Flink之TableAPI和SQL(3):通过TableAPI和SQL表的一些操作(包括查询,过滤,聚集等)
    Flink之TableAPI和SQL(2):表和外部系统的连接方式
    Flink之TableAPI和SQL(1):基本功能描述
    sb 错误
    洛谷 P6189
  • 原文地址:https://www.cnblogs.com/seusoftware/p/7929573.html
Copyright © 2011-2022 走看看