Art*_*yan 8 sql-server columnstore sql-server-2017
我有一个具有以下结构的测试表。
CREATE TABLE [dbo].[DW_test](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[CourtCaseID] [int] NOT NULL,
[ActionID] [int] NOT NULL,
PRIMARY KEY CLUSTERED([ID] ASC)
Run Code Online (Sandbox Code Playgroud)
接下来,我使用以下脚本在我的表中填充了大约 4.7 亿条记录。
insert into DW_test
--select count(*)
--from (
select top 1000000 abs(checksum(newid())) % 100000 + 1 a, abs(checksum(newid())) % 10 + 1 b
from sys.all_objects
cross join sys.all_objects a
cross join sys.all_objects b
cross join sys.all_objects c
cross join sys.all_objects d
cross join sys.all_objects e
cross join sys.all_objects f
cross join sys.all_objects g
--) t
GO
Run Code Online (Sandbox Code Playgroud)
该脚本执行了大约 470 次以在表中生成 4.7 亿条记录并在该表上创建 NCCI。
CREATE NONCLUSTERED COLUMNSTORE INDEX [IX_test1] ON [dbo].[DW_test]
(
[CourtCaseID],
[ActionID]
)
Run Code Online (Sandbox Code Playgroud)
接下来我测试简单查询以计算表中的记录数。
DBCC DROPCLEANBUFFERS
GO
select COUNT_BIG(*)
from DW_test
Run Code Online (Sandbox Code Playgroud)
如果我转,SET STATISTICS IO ON
我会得到以下结果
带冷缓存
表'DW_test'。扫描计数 25,逻辑读 3,物理读 0,预读 0,lob 逻辑读 469697,lob 物理读 1,lob 预读 1877324。
表'DW_test'。段读取 453,段跳过 0。
表“工作台”。扫描计数 0,逻辑读 0,物理读 0,预读 0,lob 逻辑读 0,lob 物理读 0,lob 预读 0。
带热缓存
表'DW_test'。扫描计数 25,逻辑读取 3,物理读取 0,预读读取 0,lob 逻辑读取 229248,lob 物理读取 0,lob 预读读取 0。
表'DW_test'。段读取 453,段跳过 0。
表“工作台”。扫描计数 0,逻辑读取 0,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。`
我知道 1 次逻辑读取是在查询执行期间从缓冲池读取的单个数据页,而 1 次物理读取是从磁盘读取的单个数据页。RedGate 告诉我们预读是:
这个数字告诉我们有多少物理读取被 SQL Server 的“预读”机制满足。这与物理读取直接相关,因此如果没有物理读取,则预读读取将为 0。
就我而言,我正在处理 lob 逻辑、物理和预读。我想了解这个数字在我的特殊情况下意味着什么。
如果表有大约 4.7 亿条记录,怎么可能只有 1 lob 物理读取和冷缓存?
lob 页面的总数怎么可能从冷缓存中的大约 230 万个减少到热缓存中的大约 22 万个?
Pau*_*ite 13
如果表有大约 4.7 亿条记录,怎么可能只有 1 lob 物理读取和冷缓存?
有 1 个 LOB 物理读取和 1,877,324 次预读。预读仍然是物理读取,只是提前执行(预取)。Redgate 的引用是不正确的。
lob 页面的总数怎么可能从冷缓存中的大约 230 万个减少到热缓存中的大约 22 万个?
逻辑读取计算内存中页面被触摸的次数。减少是从 469,697(冷缓存)到 229,248(暖缓存)。我对此没有完整的解释,但这可能部分是因为列存储数据连续缓存在单独的列存储对象池中,而不是一般的页面大小的缓冲池。
预读从 b 树的上层读取页面以识别要在扫描之前读取的页面,这也可能导致不同数量的“额外”逻辑读取,具体取决于时间和存储系统的特性. 列存储索引在持久存储上具有 b 树结构。
另一个因素是并行性(似乎您的测试是在 DOP 24 下运行的),因为来自不同线程的重叠请求会导致额外的逻辑读取。如果您使用OPTION (MAXDOP 1)
.
列存储的内部存储细节没有很好的文档记录,也没有得到通常的 DMV 的完全支持。在这个阶段,我认为冷和热缓存情况下读取减少的最好解释是磁盘和内存(缓存)存储之间的差异。
列存储数据(字典和段)存储在磁盘上的 LOB 中,但出于性能原因而不以相同的格式保存在内存中。因为它们是不同的东西,所以不能仅仅将逻辑读取添加到物理读取中以获得有意义的结果。
“如果表有大约 4.7 亿条记录,怎么可能只有 1 lob 物理读取和冷缓存?”
因为其他物理读取是由预读(LOB 类型)提供的。也许 RedGate 的文章让您感到困惑,但是如果您将某个范围(例如)作为预读 (RA),那么您将不会看到任何物理读取。收集物理读取统计信息的线程在缓存中找到了这些页面,因此它们没有累积到物理读取计数器中。
我们遇到的另一种情况是经典的缓冲区高速缓存命中率 perfmon 计数器。RA 读取不会影响此值,因此您可能有大量物理 I/O,但 BCHR 中的值仍接近 100。
“lob 页总数怎么可能从冷缓存中的约 230 万减少到热缓存中的约 220k?”
我的猜测是第一个启动了自动创建统计数据。