LIv*_*nov 2 sql sql-server select blob sql-server-2012
即使我不包含 BLOB 列,对包含 BLOB 的表进行 SELECT 查询也很慢。有人可以解释为什么,以及如何规避它吗?我使用的是 SQL Server 2012,但这可能更多是一个概念性问题,对于其他发行版也很常见。
我找到了这篇文章:SQL Server: select on a table that contains a blob,它显示了相同的问题,但标记的答案没有解释为什么会发生这种情况,也没有提供有关如何解决问题的良好建议。
小智 5
如果您正在寻求解决性能问题的方法,可以采取多种方法。如果您不是简单地选择整个记录集,则向表添加索引应该会有很大帮助。创建表视图也可能有所帮助。还值得检查表上的索引碎片级别,因为这可能会导致性能不佳,并且可以通过定期维护工作来解决。创建链接表来存储 blob 数据的建议也是一个真正好的建议。
但是,如果您的问题是询问为什么会发生这种情况,这是因为 MS SQL Server 运行方式的基本原理。本质上是您的数据库以及服务器上的所有数据库,并分为页面、带有 96 字节标头的 8kb 数据块。每个页面代表单个 I/O 操作中可能发生的情况。页面被收集并分组在扩展区(Exents)中,扩展区是八个连续页面的 64kb 集合。因此,SQL Server 每兆字节数据使用 16 个 Exents。有几种不同的页面类型,例如数据页面类型不包含所谓的“大对象”。这包括数据类型文本、图像、varbinary(max)、xml 数据等...这些也用于存储超过 8kb 的可变长度列(并且不要忘记 96 字节标头)。
每页末尾都会有少量可用空间。显然,数据库操作始终会移动这些页面,并且在处理大量 I/O 和随机记录访问/修改的数据库中,可用空间分配可能会大幅增长。这就是数据库上的可用空间会大幅增长的原因。管理套件中提供了一些工具,可让您减少或删除可用空间,基本上这会重新组织页面和扩展区。
现在,我可能在这里迈出了一步,但我猜测您表中的 blob 超过 8kb。请记住,如果它们超过 64kb,它们不仅会跨越多个页面,而且实际上会跨越多个扩展区。其最终结果将是“正常”表读取将导致大量 I/O 请求。即使您对 BLOB 数据不感兴趣,服务器也可能必须读取页面和扩展区才能获取其他表数据。随着更多事务使构成表的页和范围变得不连续,这种情况只会变得更加复杂。
在使用“大对象”的情况下,SQL Server 会写入行溢出值,其中包括指向数据实际存储位置的 24 位指针。如果表上有几列超过 8kb 页面大小(加上 blob)并受到随机事务的影响,您会发现服务器所做的大部分工作是将页面移入和移出内存的 I/O 操作,读取指针、获取关联的行数据等等...所有这些都代表着严重的开销。
| 归档时间: |
|
| 查看次数: |
5361 次 |
| 最近记录: |