查询包含varbinary(max)数据的表中的非varbinary(max)字段是否存在性能问题?

时间:2010-05-26 09:33:43

标签: sql-server performance database-design varbinary

我创建了一个表来插入我的应用程序的所有文档。它是一个简单的表(我们称之为DOC_DATA),它有3个字段:DOC_ID,FileSize,Data。数据是varbinary(max)。

然后我有许多表(CUSTOMERS_DOCUMENTS,EMPLOYEES_DOCUMENTS,...)包含其他数据(例如“文档描述”,“创建者”,“客户ID”......)。我的情况并不完全像这样,无论如何通过写这个例子我可以更好地表达自己。所有这些表都有一个FK到DOC_DATA.DOC_ID)。

当用户搜索客户文档时,他将运行类似于以下的查询:

select CD.*, DD.FileSize
from DOC_DATA DD
join CUSTOMERS_DOCUMENTS CD ON CD.DOC_ID = DD.DOC_ID

我的问题是:此查询的性能是否会很糟糕,因为我们还从一个可能很大的表中读取一个字段(DOC_DATA表可能包含许多GB数据)或者这不是问题?

另一种解决方案是将FIleSize字段放在所有主表中(CUSTOMER_DOCUMENTS,EMPLOYEES_DOCUMENTS,...)。当然,连接对性能有一点影响,现在我不是要求加入或不加入一般,而是加入或不加入一个巨大的表,而我对巨大的领域不感兴趣。

请注意:我不是在设计一个新系统,我正在维护一个遗留系统,所以在这里我不讨论哪个是最好的设计,但在这种情况下哪个是最佳选择。

1 个答案:

答案 0 :(得分:2)

我认为没有理由因为存在这些大型列而导致查询性能下降。当您读取该数据时会出现性能问题 - 特别是当您需要数据库引擎返回文档时,但您(当然)在查询中没有这样做。

在内部,对于各种yada(max)数据类型,SQL在行中存储16个左右的字节指针(或引用标记,转发记录或它们称之为的任何内容),并且实际数据存储在单独的一套页面。因此,如果您没有阅读该列,则不需要访问这些页面,也不会导致磁盘I / O命中。