当我的查询中的表都没有使用任何 LOB 数据类型字段时,为什么 IO 统计信息会在工作表上显示大量 LOB 逻辑读取?

J.D*_*.D. -3 sql-server statistics dynamic-sql sql-server-2016 performance-tuning

我有一个过程,它在数百个数据库中动态运行查询,这些数据库都具有相同的确切架构,并将结果聚合到临时表中。该查询仅涉及 3 个表(每个表都在数百万行的 10 到 100 之间,但我总共只提取了大约 50,000 行数据)。

在查看查询的汇总 IO 统计信息(通过 StatisticsParser.com - 大声喊出 Richie Rump)时,它显示创建了一个工作表,并且该工作表上有大约 550,000 个 LOB 逻辑读取。查询中所有表的常规逻辑读取总数略低于大约 400,000 次逻辑读取。

查询中的实际表都没有使用任何 LOB 数据类型,那么这到底意味着什么,它是否是我查询中瓶颈的潜在来源?

(顺便说一句,我拉回的 50,000 行数据仅相当于大约 3 MB 的数据,但我的查询在第一次运行时需要大约 10 秒才能运行(例如,当表的数据页仍在加载到内存中时) ),然后在后续运行中不到一半的时间,因此尝试查看我是否可以始终接近 <= 4s 基准测试,以及这些 LOB 逻辑读取是否与之相关。)

更新:这是一个类似的示例查询(再次查看它,我可能会发现 LOB 逻辑读取的来源)。

过程签名: sp_StoredProc_ToGetData (@IdsTable TVP (Id INT), @StartDate DateTime, @EndDate DateTime)

sp_StoredProc_ToGetData 内部的查询:

SELECT Id
INTO #IdsTableTemp
FROM @IdsTable;

-- This query is ran using dynamic SQL but for the example simplicity this is just the root query itself    
SELECT 'SomeConstant' AS Field1, T1.Field2, T1.Field3, T3.Field4, T3.Field5
FROM Table1 AS T1
INNER JOIN Table2 AS T2 -- Linking table between T1 and T3
    ON T1.PrimaryKey = T2.PrimaryKey
INNER JOIN Table3 AS T3
    ON T2.NonClusteredIndexField = T3.PrimaryKey
WHERE T1.Date >= @StartDate
    AND T2.Date < @EndDate
Run Code Online (Sandbox Code Playgroud)

更新 2:动态运行的主查询的执行计划 执行计划

更新 3:计算机标量运算符属性 计算标量运算符属性

Jos*_*ell 6

根据您的问题描述:

  • 神秘的工作台
  • 从工作表读取高 LOB
  • 查询中没有 LOB 列
  • 冷缓存与热缓存不成比例地慢

听起来您遇到了这个问题:执行计划分析:神秘工作表

寻找一个计算标量,它在输出时生成 LOB 数据类型,然后流入带有预取的嵌套循环连接。

解决这个问题在很大程度上取决于您的源查询,但是需要做一些事情来将 LOB 数据移过循环连接,或者可能获得不同的连接类型。