AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 203063
Accepted
Josh Darnell
Josh Darnell
Asked: 2018-04-05 11:49:25 +0800 CST2018-04-05 11:49:25 +0800 CST 2018-04-05 11:49:25 +0800 CST

为什么 CHECKDB 读取具有内存优化表的数据库上的事务日志文件?

  • 772

tl;dr:为什么 CHECKDB 读取具有内存优化表的用户数据库的事务日志?


看起来 CHECKDB 在检查我的一个数据库时正在读取用户数据库的事务日志文件 - 特别是使用内存中 OLTP 表的数据库。

该数据库的 CHECKDB 仍会在合理的时间内完成,所以我主要只是对这种行为感到好奇;但它绝对是该实例上所有数据库中 CHECKDB 持续时间最长的。

在查看 Paul Randal 的史诗“ CHECKDB From Every Angle:所有 CHECKDB 阶段的完整描述”时,我看到 SQL 2005 之前的 CHECKDB用于读取日志以获得数据库的一致视图。但由于这是 2016 年,它使用内部数据库快照。

但是,快照的先决条件之一是:

源数据库不得包含 MEMORY_OPTIMIZED_DATA 文件组

我的用户数据库有这些文件组之一,所以看起来快照不在表中。

根据CHECKDB 文档:

如果无法创建快照,或指定了 TABLOCK,DBCC CHECKDB 将获取锁以获得所需的一致性。在这种情况下,需要独占数据库锁来执行分配检查,并且需要共享表锁来执行表检查。

好的,所以我们正在执行数据库和表锁定而不是快照。但这仍然不能解释为什么它必须读取事务日志。那么给出了什么?

我在下面提供了一个脚本来重现该场景。它用于sys.dm_io_virtual_file_stats标识日志文件读取。

请注意,大多数时候它只读取日志的一小部分 (480 KB),但偶尔会读取更多 (48.2 MB)。在我的生产场景中,当我们运行 CHECKDB 时,它会在每晚午夜读取大部分日志文件(2 GB 文件中的约 1.3 GB)。

这是到目前为止我使用脚本获得的输出示例:

collection_time            num_of_reads     num_of_bytes_read
2018-04-04 15:12:29.203    106              50545664

或这个:

collection_time            num_of_reads     num_of_bytes_read
2018-04-04 15:25:14.227    1                491520

如果我用常规表替换内存优化对象,输出如下所示:

collection_time            num_of_reads     num_of_bytes_read
2018-04-04 15:21:03.207    0                0

为什么 CHECKDB 正在读取日志文件?特别是,为什么它偶尔会读取日志文件的大部分内容?

这是实际的脚本:

-- let's have a fresh DB
USE [master];

IF (DB_ID(N'LogFileRead_Test') IS NOT NULL) 
BEGIN
    ALTER DATABASE [LogFileRead_Test]
    SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    DROP DATABASE [LogFileRead_Test];
END

GO
CREATE DATABASE [LogFileRead_Test]

GO
ALTER DATABASE [LogFileRead_Test]
MODIFY FILE
(
    NAME = LogFileRead_Test_log,
    SIZE = 128MB
);

-- Hekaton-yeah, I want memory optimized data
GO
ALTER DATABASE [LogFileRead_Test]
ADD FILEGROUP [LatencyTestInMemoryFileGroup] CONTAINS MEMORY_OPTIMIZED_DATA;

GO
ALTER DATABASE [LogFileRead_Test]
ADD FILE 
(
    NAME = [LatencyTestInMemoryFile], 
    FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL13.SQL2016\MSSQL\DATA\LogFileRead_Test_SessionStateInMemoryFile'
) TO FILEGROUP [LatencyTestInMemoryFileGroup];

GO
USE [LogFileRead_Test]

GO
CREATE TYPE [dbo].[InMemoryIdTable] AS TABLE (
    [InMemoryId] NVARCHAR (88) COLLATE Latin1_General_100_BIN2 NOT NULL,
    PRIMARY KEY NONCLUSTERED HASH ([InMemoryId]) WITH (BUCKET_COUNT = 240))
    WITH (MEMORY_OPTIMIZED = ON);

GO
CREATE TABLE [dbo].[InMemoryStuff] (
    [InMemoryId]   NVARCHAR (88)    COLLATE Latin1_General_100_BIN2 NOT NULL,
    [Created]     DATETIME2 (7)    NOT NULL,
    CONSTRAINT [PK_InMemoryStuff_InMemoryId] PRIMARY KEY NONCLUSTERED HASH ([InMemoryId]) WITH (BUCKET_COUNT = 240)
)
WITH (MEMORY_OPTIMIZED = ON);

GO
-- RBAR is the new black (we need some logs to read)
declare @j int = 0;
while @j < 100000
begin
    INSERT INTO [dbo].[InMemoryStuff](InMemoryId, Created) VALUES ('Description' + CAST(@j as varchar), GETDATE());
    set @j = @j + 1;
end

-- grab a baseline of virtual file stats to be diff'd later
select f.num_of_reads, f.num_of_bytes_read
into #dm_io_virtual_file_stats
from sys.dm_io_virtual_file_stats(default, default) f
where database_id = db_id('LogFileRead_Test') and file_id = FILE_IDEX('LogFileRead_Test_log');

-- hands off my log file, CHECKDB!
GO
DBCC CHECKDB ([LogFileRead_Test]) WITH NO_INFOMSGS, ALL_ERRORMSGS, DATA_PURITY;

-- grab the latest virtual file stats, and compare with the previous capture
GO
select f.num_of_reads, f.num_of_bytes_read
into #checkdb_stats
from sys.dm_io_virtual_file_stats(default, default) f
where database_id = db_id('LogFileRead_Test') and file_id = FILE_IDEX('LogFileRead_Test_log');

select 
        collection_time = GETDATE() 
        , num_of_reads = - f.num_of_reads + t.num_of_reads
        , num_of_bytes_read = - f.num_of_bytes_read + t.num_of_bytes_read
into #dm_io_virtual_file_stats_diff
from #dm_io_virtual_file_stats f, #checkdb_stats t;

drop table #checkdb_stats;
drop table #dm_io_virtual_file_stats;

-- CHECKDB ignored my comment
select collection_time, num_of_reads, num_of_bytes_read
from #dm_io_virtual_file_stats_diff d
order by d.collection_time;

drop table #dm_io_virtual_file_stats_diff;

-- I was *not* raised in a barn
USE [master];

ALTER DATABASE [LogFileRead_Test]
SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE [LogFileRead_Test];

由于此重现通常只生成 1 或 106 次日志文件读取,我想我会使用 file_read 和 file_read_completed 扩展事件会话深入研究 1。

name                timestamp                   mode        offset  database_id file_id size    duration
file_read           2018-04-06 10:51:11.1098141 Contiguous  72704   9           2       0       NULL    
file_read_completed 2018-04-06 10:51:11.1113345 Contiguous  72704   9           2       491520  1       

这是 VLF 详细信息 ( DBCC LOGINFO()),用于这些偏移量的上下文等:

RecoveryUnitId  FileId  FileSize    StartOffset FSeqNo  Status  Parity  CreateLSN
0               2       2031616     8192        34      2       64      0
0               2       2031616     2039808     35      2       64      0
0               2       2031616     4071424     36      2       64      0
0               2       2285568     6103040     37      2       64      0
0               2       15728640    8388608     38      2       64      34000000005200001
0               2       15728640    24117248    39      2       64      34000000005200001
0               2       15728640    39845888    40      2       64      34000000005200001
0               2       15728640    55574528    0       0       0       34000000005200001
0               2       15728640    71303168    0       0       0       34000000005200001
0               2       15728640    87031808    0       0       0       34000000005200001
0               2       15728640    102760448   0       0       0       34000000005200001
0               2       15728640    118489088   0       0       0       34000000005200001

因此,CHECKDB 操作:

  • 开始将 63 KB(64,512 字节)读入第一个 VLF,
  • 读取 480 KB(491,520 字节),以及
  • 没有读取 VLF的最后 1441 KB(1,475,584 字节)

我还捕获了调用堆栈,以防它们有帮助。

file_read 调用堆栈:

(00007ffd`999a0860)   sqlmin!XeSqlPkg::file_read::Publish+0x1dc   |  (00007ffd`999a0b40)   sqlmin!XeSqlPkg::file_read_enqueued::Publish
(00007ffd`9a825e30)   sqlmin!FireReadEvent+0x118   |  (00007ffd`9a825f60)   sqlmin!FireReadEnqueuedEvent
(00007ffd`9980b500)   sqlmin!FCB::AsyncRead+0x74d   |  (00007ffd`9980b800)   sqlmin!FCB::AsyncReadInternal
(00007ffd`9970e9d0)   sqlmin!SQLServerLogMgr::LogBlockReadAheadAsync+0x6a6   |  (00007ffd`9970ec00)   sqlmin!LBH::Destuff
(00007ffd`9970a6d0)   sqlmin!LogConsumer::GetNextLogBlock+0x1591   |  (00007ffd`9970ab70)   sqlmin!LogPoolPrivateCacheBufferMgr::Lookup
(00007ffd`9a9fcbd0)   sqlmin!SQLServerLogIterForward::GetNext+0x258   |  (00007ffd`9a9fd2d0)   sqlmin!SQLServerLogIterForward::GetNextBlock
(00007ffd`9aa417f0)   sqlmin!SQLServerCOWLogIterForward::GetNext+0x2b   |  (00007ffd`9aa418c0)   sqlmin!SQLServerCOWLogIterForward::StartScan
(00007ffd`9aa64210)   sqlmin!RecoveryMgr::AnalysisPass+0x83b   |  (00007ffd`9aa65100)   sqlmin!RecoveryMgr::AnalyzeLogRecord
(00007ffd`9aa5ed50)   sqlmin!RecoveryMgr::PhysicalRedo+0x233   |  (00007ffd`9aa5f790)   sqlmin!RecoveryMgr::PhysicalCompletion
(00007ffd`9aa7fd90)   sqlmin!RecoveryUnit::PhysicalRecovery+0x358   |  (00007ffd`9aa802c0)   sqlmin!RecoveryUnit::CompletePhysical
(00007ffd`9a538b90)   sqlmin!StartupCoordinator::NotifyPhaseStart+0x3a   |  (00007ffd`9a538bf0)   sqlmin!StartupCoordinator::NotifyPhaseEnd
(00007ffd`9a80c430)   sqlmin!DBTABLE::ReplicaCreateStartup+0x2f4   |  (00007ffd`9a80c820)   sqlmin!DBTABLE::RefreshPostRecovery
(00007ffd`9a7ed0b0)   sqlmin!DBMgr::SyncAndLinkReplicaRecoveryPhase+0x890   |  (00007ffd`9a7edff0)   sqlmin!DBMgr::DetachDB
(00007ffd`9a7f2cd0)   sqlmin!DBMgr::CreatePhasedTransientReplica+0x869   |  (00007ffd`9a7f3630)   sqlmin!DBMgr::StrandTransientReplica
(00007ffd`9a7f2ae0)   sqlmin!DBMgr::CreateTransientReplica+0x118   |  (00007ffd`9a7f2cd0)   sqlmin!DBMgr::CreatePhasedTransientReplica
(00007ffd`99ec6d30)   sqlmin!DBDDLAgent::CreateReplica+0x1b5   |  (00007ffd`99ec6f90)   sqlmin!FSystemDatabase
(00007ffd`9abaaeb0)   sqlmin!UtilDbccCreateReplica+0x82   |  (00007ffd`9abab000)   sqlmin!UtilDbccDestroyReplica
(00007ffd`9ab0d7e0)   sqlmin!UtilDbccCheckDatabase+0x994   |  (00007ffd`9ab0ffd0)   sqlmin!UtilDbccRetainReplica
(00007ffd`9ab0cfc0)   sqlmin!DbccCheckDB+0x22d   |  (00007ffd`9ab0d380)   sqlmin!DbccCheckFilegroup
(00007ffd`777379c0)   sqllang!DbccCommand::Execute+0x193   |  (00007ffd`77737d70)   sqllang!DbccHelp
(00007ffd`777e58d0)   sqllang!CStmtDbcc::XretExecute+0x889   |  (00007ffd`777e6250)   sqllang!UtilDbccSetPermissionFailure
(00007ffd`76b02eb0)   sqllang!CMsqlExecContext::ExecuteStmts<1,1>+0x40d   |  (00007ffd`76b03410)   sqllang!CSQLSource::CleanupCompileXactState
(00007ffd`76b03a60)   sqllang!CMsqlExecContext::FExecute+0xa9e   |  (00007ffd`76b043d0)   sqllang!CCacheObject::Release
(00007ffd`76b03430)   sqllang!CSQLSource::Execute+0x981   |  (00007ffd`76b039b0)   sqllang!CSQLLock::Cleanup

file_read_completed 调用堆栈:

(00007ffd`99995cc0)   sqlmin!XeSqlPkg::file_read_completed::Publish+0x1fc   |  (00007ffd`99995fe0)   sqlmin!XeSqlPkg::file_write_completed::Publish
(00007ffd`9a826630)   sqlmin!FireIoCompletionEventLong+0x227   |  (00007ffd`9a8269c0)   sqlmin!IoRequestDispenser::Dump
(00007ffd`9969bee0)   sqlmin!FCB::IoCompletion+0x8e   |  (00007ffd`9969c180)   sqlmin!IoRequestDispenser::Put
(00007ffd`beaa11e0)   sqldk!IOQueue::CheckForIOCompletion+0x426   |  (00007ffd`beaa1240)   sqldk!SystemThread::GetCurrentId
(00007ffd`beaa15b0)   sqldk!SOS_Scheduler::SwitchContext+0x173   |  (00007ffd`beaa18a0)   sqldk!SOS_Scheduler::Switch
(00007ffd`beaa1d00)   sqldk!SOS_Scheduler::SuspendNonPreemptive+0xd3   |  (00007ffd`beaa1db0)   sqldk!SOS_Scheduler::ResumeNoCuzz
(00007ffd`99641720)   sqlmin!EventInternal<SuspendQueueSLock>::Wait+0x1e7   |  (00007ffd`99641ae0)   sqlmin!SOS_DispatcherPool<DispatcherWorkItem,DispatcherWorkItem,SOS_DispatcherQueue<DispatcherWorkItem,0,DispatcherWorkItem>,DispatcherPoolConfig,void * __ptr64>::GetDispatchers
(00007ffd`9aa437c0)   sqlmin!SQLServerLogMgr::CheckLogBlockReadComplete+0x1e6   |  (00007ffd`9aa44670)   sqlmin!SQLServerLogMgr::ValidateBlock
(00007ffd`9970a6d0)   sqlmin!LogConsumer::GetNextLogBlock+0x1b37   |  (00007ffd`9970ab70)   sqlmin!LogPoolPrivateCacheBufferMgr::Lookup
(00007ffd`9a9fcbd0)   sqlmin!SQLServerLogIterForward::GetNext+0x258   |  (00007ffd`9a9fd2d0)   sqlmin!SQLServerLogIterForward::GetNextBlock
(00007ffd`9aa417f0)   sqlmin!SQLServerCOWLogIterForward::GetNext+0x2b   |  (00007ffd`9aa418c0)   sqlmin!SQLServerCOWLogIterForward::StartScan
(00007ffd`9aa64210)   sqlmin!RecoveryMgr::AnalysisPass+0x83b   |  (00007ffd`9aa65100)   sqlmin!RecoveryMgr::AnalyzeLogRecord
(00007ffd`9aa5ed50)   sqlmin!RecoveryMgr::PhysicalRedo+0x233   |  (00007ffd`9aa5f790)   sqlmin!RecoveryMgr::PhysicalCompletion
(00007ffd`9aa7fd90)   sqlmin!RecoveryUnit::PhysicalRecovery+0x358   |  (00007ffd`9aa802c0)   sqlmin!RecoveryUnit::CompletePhysical
(00007ffd`9a538b90)   sqlmin!StartupCoordinator::NotifyPhaseStart+0x3a   |  (00007ffd`9a538bf0)   sqlmin!StartupCoordinator::NotifyPhaseEnd
(00007ffd`9a80c430)   sqlmin!DBTABLE::ReplicaCreateStartup+0x2f4   |  (00007ffd`9a80c820)   sqlmin!DBTABLE::RefreshPostRecovery
(00007ffd`9a7ed0b0)   sqlmin!DBMgr::SyncAndLinkReplicaRecoveryPhase+0x890   |  (00007ffd`9a7edff0)   sqlmin!DBMgr::DetachDB
(00007ffd`9a7f2cd0)   sqlmin!DBMgr::CreatePhasedTransientReplica+0x869   |  (00007ffd`9a7f3630)   sqlmin!DBMgr::StrandTransientReplica
(00007ffd`9a7f2ae0)   sqlmin!DBMgr::CreateTransientReplica+0x118   |  (00007ffd`9a7f2cd0)   sqlmin!DBMgr::CreatePhasedTransientReplica
(00007ffd`99ec6d30)   sqlmin!DBDDLAgent::CreateReplica+0x1b5   |  (00007ffd`99ec6f90)   sqlmin!FSystemDatabase
(00007ffd`9abaaeb0)   sqlmin!UtilDbccCreateReplica+0x82   |  (00007ffd`9abab000)   sqlmin!UtilDbccDestroyReplica
(00007ffd`9ab0d7e0)   sqlmin!UtilDbccCheckDatabase+0x994   |  (00007ffd`9ab0ffd0)   sqlmin!UtilDbccRetainReplica
(00007ffd`9ab0cfc0)   sqlmin!DbccCheckDB+0x22d   |  (00007ffd`9ab0d380)   sqlmin!DbccCheckFilegroup
(00007ffd`777379c0)   sqllang!DbccCommand::Execute+0x193   |  (00007ffd`77737d70)   sqllang!DbccHelp

这些堆栈跟踪与Max 的回答相关联,表明 CHECKDB 正在使用内部快照,尽管存在 Hekaton 表。

我读过快照执行恢复以撤消未提交的事务:

未提交的事务在新创建的数据库快照中回滚,因为数据库引擎在创建快照后运行恢复(数据库中的事务不受影响)。

但这仍然不能解释为什么在我的生产场景中经常读取大量日志文件(偶尔在此处提供的重现中)。我不认为我的应用程序在给定时间有那么多飞行中的交易,而且这里的 repro 中肯定没有任何交易。

sql-server sql-server-2016
  • 1 1 个回答
  • 977 Views

1 个回答

  • Voted
  1. Best Answer
    Hannah Vernon
    2018-04-07T11:17:37+08:002018-04-07T11:17:37+08:00

    尽管 SQL Server 文档指出具有“内存中”表的数据库不支持快照,但DBCC CHECKDB仍然可以创建所需的“内部”快照,因为 checkdb 操作不涉及内存中表,并且快照仅捕获更改到磁盘表。

    据推测,微软选择阻止用户在具有内存表的数据库上创建快照,因为他们需要复制内存中的结构,以便快照真正成为正常的、以用户为中心的意义上的完整快照。为快照复制内存表很容易使服务器内存不足,这不是一件好事™

    您可以通过在运行时查看主数据库数据文件所在的数据文件夹来证明正在创建内部 DBCC 快照DBCC CHECKDB。如果创建了内部快照,您将看到一个名为LogFileRead_Test.mdf_MSSQL_DBCC7(7可能不同 - 它代表您的数据库的数据库 ID)的文件。

    创建快照文件后,SQL Server 需要对数据库运行恢复,以使其进入运行 DBCC CHECKDB 所需的一致状态。您看到的任何日志读取操作都可能是该恢复过程的结果。我构建了一个快速装置来检查多个DBCC CHECKDB操作的输出,这证明如果 checkdbs 之间没有事务,就没有日志文件读取。

    USE master;
    SET IMPLICIT_TRANSACTIONS OFF;
    USE [master];
    IF (DB_ID(N'LogFileRead_Test') IS NOT NULL) 
    BEGIN
        ALTER DATABASE [LogFileRead_Test]
        SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
        DROP DATABASE [LogFileRead_Test];
    END
    
    CREATE DATABASE [LogFileRead_Test]
    ALTER DATABASE [LogFileRead_Test]
    MODIFY FILE
    (
        NAME = LogFileRead_Test_log,
        SIZE = 128MB
    );
    
    ALTER DATABASE [LogFileRead_Test]
    ADD FILEGROUP [LatencyTestInMemoryFileGroup] CONTAINS MEMORY_OPTIMIZED_DATA;
    ALTER DATABASE [LogFileRead_Test]
    ADD FILE 
    (
        NAME = [LatencyTestInMemoryFile], 
        FILENAME = 'C:\temp\LogFileRead_Test_SessionStateInMemoryFile'
    ) TO FILEGROUP [LatencyTestInMemoryFileGroup];
    GO
    
    USE LogFileRead_Test;
    
    CREATE TABLE [dbo].[InMemoryStuff] (
        [InMemoryId]   NVARCHAR (88)    COLLATE Latin1_General_100_BIN2 NOT NULL,
        [Created]     DATETIME2 (7)    NOT NULL,
        CONSTRAINT [PK_InMemoryStuff_InMemoryId] 
        PRIMARY KEY NONCLUSTERED 
        HASH ([InMemoryId]) WITH (BUCKET_COUNT = 240)
    )
    WITH (MEMORY_OPTIMIZED = ON);
    
    ;WITH src AS (
        SELECT n.Num
        FROM (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9))n(Num)
    )
    INSERT INTO [dbo].[InMemoryStuff] (InMemoryId, Created) 
    SELECT 'Description' + CONVERT(varchar(30)
            , ((s1.Num * 10000) 
             + (s2.Num * 1000) 
             + (s3.Num * 100) 
             + (s4.Num * 10) 
             + (s5.Num)))
        , GETDATE()
    FROM src s1
        CROSS JOIN src s2
        CROSS JOIN src s3
        CROSS JOIN src s4
        CROSS JOIN src s5;
    USE master;
    
    DECLARE @cmd nvarchar(max);
    DECLARE @msg nvarchar(1000);
    DECLARE @l int;
    DECLARE @m int;
    SET @m = 10;
    SET @l = 1;
    IF OBJECT_ID(N'tempdb..#vfs', N'U') IS NOT NULL DROP TABLE #vfs;
    CREATE TABLE #vfs (
        vfs_run int NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED
        , collection_time datetime2(7)
        , num_of_reads bigint
        , num_of_bytes_read bigint
    );
    
    WHILE @l <= @m 
    BEGIN
    SET @msg = N'loop ' + CONVERT(nvarchar(10), @l);
    RAISERROR (@msg, 0, 1) WITH NOWAIT;
    
    SET @cmd = 'USE [LogFileRead_Test];
    -- grab a baseline of virtual file stats to be diff''d later
    select f.num_of_reads, f.num_of_bytes_read
    into #dm_io_virtual_file_stats
    from sys.dm_io_virtual_file_stats(default, default) f
    where database_id = db_id(''LogFileRead_Test'') and file_id = FILE_IDEX(''LogFileRead_Test_log'');
    
    DBCC CHECKDB ([LogFileRead_Test]) WITH NO_INFOMSGS, ALL_ERRORMSGS, DATA_PURITY;
    
    -- grab the latest virtual file stats, and compare with the previous capture
    select f.num_of_reads, f.num_of_bytes_read
    into #checkdb_stats
    from sys.dm_io_virtual_file_stats(default, default) f
    where database_id = db_id(''LogFileRead_Test'') and file_id = FILE_IDEX(''LogFileRead_Test_log'');
    
    select 
            collection_time = GETDATE() 
            , num_of_reads = - f.num_of_reads + t.num_of_reads
            , num_of_bytes_read = - f.num_of_bytes_read + t.num_of_bytes_read
    into #dm_io_virtual_file_stats_diff
    from #dm_io_virtual_file_stats f, #checkdb_stats t;
    
    --drop table #checkdb_stats;
    --drop table #dm_io_virtual_file_stats;
    
    -- CHECKDB ignored my comment
    select collection_time, num_of_reads, num_of_bytes_read
    from #dm_io_virtual_file_stats_diff d
    order by d.collection_time;
    
    --drop table #dm_io_virtual_file_stats_diff;
    ';
    INSERT INTO #vfs (collection_time, num_of_reads, num_of_bytes_read)
    EXEC sys.sp_executesql @cmd;
    
    SET @l += 1;
    END
    
    USE master;
    SET @cmd = 'USE [master];
    ALTER DATABASE [LogFileRead_Test]
    SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    DROP DATABASE [LogFileRead_Test];
    ';
    EXEC sys.sp_executesql @cmd;
    
    SELECT *
    FROM #vfs
    ORDER BY vfs_run;
    

    结果:

    ╔═════════╦═════════════════════════════╦══════════════╦═══════════════════╗
    ║ vfs_run ║       collection_time       ║ num_of_reads ║ num_of_bytes_read ║
    ╠═════════╬═════════════════════════════╬══════════════╬═══════════════════╣
    ║       1 ║ 2018-04-06 15:53:37.6566667 ║            1 ║            491520 ║
    ║       2 ║ 2018-04-06 15:53:37.8300000 ║            0 ║                 0 ║
    ║       3 ║ 2018-04-06 15:53:38.0166667 ║            0 ║                 0 ║
    ║       4 ║ 2018-04-06 15:53:38.1866667 ║            0 ║                 0 ║
    ║       5 ║ 2018-04-06 15:53:38.3766667 ║            0 ║                 0 ║
    ║       6 ║ 2018-04-06 15:53:38.5633333 ║            0 ║                 0 ║
    ║       7 ║ 2018-04-06 15:53:38.7333333 ║            0 ║                 0 ║
    ║       8 ║ 2018-04-06 15:53:38.9066667 ║            0 ║                 0 ║
    ║       9 ║ 2018-04-06 15:53:39.0933333 ║            0 ║                 0 ║
    ║      10 ║ 2018-04-06 15:53:39.2800000 ║            0 ║                 0 ║
    ╚═════════╩═════════════════════════════╩══════════════╩═══════════════════╝
    

    Also, instead of using an RBAR approach for inserting data into the test table, you may want to use a simple set-based approach, such as the one below:

    ;WITH src AS (
        SELECT n.Num
        FROM (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9))n(Num)
    )
    INSERT INTO [dbo].[InMemoryStuff] (InMemoryId, Created) 
    SELECT 'Description' + CONVERT(varchar(30)
         , ((s1.Num * 10000) 
          + (s2.Num * 1000) 
          + (s3.Num * 100) 
          + (s4.Num * 10) 
          + (s5.Num)))
        , GETDATE()
    FROM src s1
        CROSS JOIN src s2
        CROSS JOIN src s3
        CROSS JOIN src s4
        CROSS JOIN src s5;
    

    In my test, it fills the table in under 3 seconds, whereas the RBAR approach takes a long time. Also, nice comments in your code, made me lol.

    • 10

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve