Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么对带有blob的表执行Select SQL查询速度很慢,即使没有选择blob?_Sql_Sql Server_Select_Sql Server 2012_Blob - Fatal编程技术网

为什么对带有blob的表执行Select SQL查询速度很慢,即使没有选择blob?

为什么对带有blob的表执行Select SQL查询速度很慢,即使没有选择blob?,sql,sql-server,select,sql-server-2012,blob,Sql,Sql Server,Select,Sql Server 2012,Blob,对带有BLOB的表的SELECT查询速度很慢,即使我没有包含BLOB列。有人能解释为什么,或者如何规避它吗?我使用的是SQL Server 2012,但这可能是一个概念性问题,其他发行版也会遇到这个问题 我发现了这篇帖子:,它显示了同样的问题,但标记的答案并不能解释为什么会发生这种情况,也不能提供解决问题的好建议。我当时得到了一个建议,将所有blob放在一个单独的表中,并带有标识ID,然后只将标识ID保存在主表中 这可能是因为-也许SQL不能像缓存表页那样容易,而且您必须更频繁地访问磁盘。但我不

对带有BLOB的表的SELECT查询速度很慢,即使我没有包含BLOB列。有人能解释为什么,或者如何规避它吗?我使用的是SQL Server 2012,但这可能是一个概念性问题,其他发行版也会遇到这个问题


我发现了这篇帖子:,它显示了同样的问题,但标记的答案并不能解释为什么会发生这种情况,也不能提供解决问题的好建议。

我当时得到了一个建议,将所有blob放在一个单独的表中,并带有标识ID,然后只将标识ID保存在主表中


这可能是因为-也许SQL不能像缓存表页那样容易,而且您必须更频繁地访问磁盘。但我不知道为什么


很多人对数据库中的blob/images表示不满-在SQL 2012中,存在某种折衷方案,您可以将DB配置为将对象保留在文件结构中,而不再保留在实际的DB中-如果您想找到一种解决性能问题的方法,您可能需要寻找这种方法,您可以采取多种方法。如果您不只是选择整个记录集,那么向表中添加索引应该会有很大帮助。在表上创建视图也可能有帮助。还值得检查表上的索引碎片级别,因为这可能会导致性能低下,并且可以通过定期维护工作来解决。创建一个链接表来存储blob数据的建议也是一个非常好的建议

然而,如果您的问题是问为什么会发生这种情况,这是因为MS SQL Server的基本功能。基本上是您的数据库和服务器上的所有数据库,并拆分为页面、8kb的数据块和96字节的头。每个页面表示单个I/O操作中可能的内容。页面被收集并包含在Exents中,Exents是由8个连续页面组成的64kb的集合。因此,SQL Server每兆字节数据使用16个EXENT。有几种不同的页面类型,例如数据页面类型不包含所谓的“大对象”。这包括数据类型text、image、varbinary(max)、xml数据等。。。它们还用于存储超过8kb的可变长度列(不要忘记96字节的标题)

在每一页的末尾都会有少量的空闲空间。显然,数据库操作会一直移动这些页面,在处理大量I/O和随机记录访问/修改的数据库中,可用空间分配可能会大量增加。这就是为什么数据库上的可用空间会大量增加。管理套件中提供了一些工具,允许您减少或删除可用空间,基本上可以重新组织页面和EXENT

现在,我可能在这里做了一个飞跃,但我猜您的表中的blob超过8kb。请记住,如果它们超过64kb,它们将不仅跨越多个页面,而且确实跨越多个exents。这样做的最终结果是“正常”表读取将导致大量I/O请求。即使您对BLOB数据不感兴趣,服务器也可能需要通读页面和EXENT以获取其他表数据。只有当更多的事务使组成表的页面和EXENT变得不连续时,这种情况才会变得更加复杂


在使用“大型对象”的情况下,SQL Server会写入行溢出值,其中包括指向数据实际存储位置的24位指针。如果您的表中有几列超过8kb的页面大小,加上BLOB并受到随机事务的影响,那么您会发现服务器所做的大部分工作都是I/O操作,用于将页面移入和移出内存、读取指针、获取相关行数据等。。。所有这些都意味着严重的开销。

您是否也在使用SQL Server?SQL Server 2012 R2,但我想这对于许多MS SQL Server版本以及其他SQL Server来说都很常见?可能是因为-可能SQL无法轻松缓存表页,您必须更频繁地访问磁盘。我不知道为什么——如果真的发生了,那么试试我提到的表格重新设计,如果你真的需要这个blob,那就做一次吧join@AndrewDeighton,您指的是SQL Server,不是SQL…是的,SQL Server抱歉-您可能想查看FILESTREAM,我想这是最好的方式,只是这并不能回答问题,原因是什么。另外,目前我的公司还没有办法开始进行这种改变,所以我正在寻找一种不同的方法。很好。你是说在使用“大对象”的地方,SQL server会将一些指针写入到另一个实际存储大对象的地方(你猜对了,我的对象在50KB到3MB之间)。那么,为什么引擎在BLOB参考点所在的位置加载任何东西呢?如果我做了一个不包含BLOB的查询,为什么要去获取它呢?或者如果BLOB所在的EXENT包含更多数据?那么,如果它们是连续的,并且我的BLOB跨越了10个,那么为什么要把它们全部取出来,而不仅仅是第一个和最后一个;无法保证它们是按顺序(甚至连续)存储的。不要假设一个50kb的对象驻留在7个页面中,因此这是一个exent。构成这个对象的7页很可能存在于两个、三个甚至七个不同的版本中。我现在明白了。谢谢你把这件事弄清楚。也许将它添加到您的答案中,以便任何可能遇到相同问题的人都能完全清楚:)向上投票,顺便说一句,它应该是范围,而不是exents。