SQL 具有大型 varchar 列的服务器 select 需要时间来加载

SQL Server select with large varchar columns take time to load

我正在尝试 运行 一个简单的 select 查询,它在 select 列列表中有名为 instructions with varchar(8000) 的列。 table 有 90,000 条记录,我的 SQL 服务器管理工​​作室控制台用了 10 秒 return 并显示完整的 table 数据

SELECT id, name, instructions, etc.... FROM TABLE;

然而,当我从 select 列表中删除指令时,执行和显示结果只用了 1 秒。谁能帮我理解这背后的理论

谢谢 凯斯

这里有一些明显的东西会影响时间,还有一些更微妙的东西。 SQL Server 的底层存储以及它如何存储/检索这些数据的主题本身就是一本书,其中有很多。 (我个人推荐 Kalen Delaney,但每个人都会有自己的偏好,我很欣赏我们应该远离 SO 的主观性)。

  • 如果您是从服务器以外的另一台计算机连接的,则可能必须通过网络连接整理 90k 行指令。
  • SSMS 控制台本身必须显示这些,这本身需要时间。
  • 根据您正在读取的内容与缓冲区缓存和正在执行的其他查询的大小,您可能会对缓存施加压力并为整个服务器产生更多的物理 IO 负载。
  • 如评论中所述,正在读取更多数据,但这是否意味着正在从磁盘读取更多数据?仔细看这个要微妙得多。

在磁盘IO问题上,取决于指令在行中的放置时间和数据内联周围列的设置。可能是该行的指令与该行内联存储,这意味着实际上没有发生额外的磁盘 IO 来读取它们而不是读取它们,更多的是 SQL 服务器是否费心解码值来自内存中的页面。

varchar(8000) 虽然可能不会与其余数据内联,但它可能位于 row_overflow_data 页上,有时称为短大对象 (SLOB),在这种情况下,指令字段本身存储一个存储数据的指针,当您阅读指令时,它会导致 SQL 服务器必须每行读取磁盘上其他地方的另一个完全随机的页面(和范围)。

根据添加指令的方式/时间,您可能会看到为这些指令分配的大量碎片/缺少连续范围,尽管这取决于 IO 子系统,这可能对问题无关紧要。

此时有很多未知数,这使得给出任何确定的东西变得更加困难 - 你在数据库的 'it depends' 区域,这需要更多的细节和调查才能指出具体原因,而不是上面更笼统(但不完整)的列表。

正如 Tim Biegeleisen 提到的,除非必要,否则不要阅读说明。