尽管我不同意BLOB应该只在另一个表中,但它们根本不应该在数据库中。将指针存储到文件在磁盘上的位置,然后从数据库中获取指针。
他们(对我而言)引起的主要问题是索引。将XML与查询计划一起使用,因为每个人都有自己的名字,所以让我们创建一个表:
SELECT TOP 1000
ID = IDENTITY(INT,1,1),
deq.query_plan
INTO dbo.index_test
FROM sys.dm_exec_cached_plans AS dec
CROSS APPLY sys.dm_exec_query_plan(dec.plan_handle) AS deq
ALTER TABLE dbo.index_test ADD CONSTRAINT pk_id PRIMARY KEY CLUSTERED (ID)
它只有1000行,但是要检查大小 ...
sp_BlitzIndex @DatabaseName = 'StackOverflow', @SchemaName = 'dbo', @TableName = 'index_test'
仅1000行就超过40 MB。假设每1000行添加40 MB,那么很快就会变得很丑。当您达到一百万行时会发生什么?那里只有1 TB的数据。
现在,任何需要使用聚簇索引的查询都需要将所有BLOB数据读入内存中,以澄清:引用BLOB数据列时。
与存储BLOB相比,您能想到使用SQL Server内存的更好方法吗?因为我肯定可以。
将其扩展为非聚集索引:
CREATE INDEX ix_noblob ON dbo.index_test (ID)
CREATE INDEX ix_returnoftheblob ON dbo.index_test (ID) INCLUDE (query_plan)
您可以设计非聚集索引以在很大程度上避免使用BLOB列,以便常规查询可以避免聚集索引,但是一旦需要该BLOB列,就需要聚集索引。
如果将它作为一INCLUDED
列添加到非聚集索引中,以避免出现关键查找情况,则最终会出现巨大的非聚集索引:
它们引起的更多问题:
- 如果有人运行
SELECT *
查询,他们将获得所有BLOB数据。
- 它们占用了备份和还原空间,从而降低了速度
- 他们放慢脚步
DBCC CHECKDB
,因为我知道您正在检查腐败,对吗?
- 而且,如果您进行任何索引维护,它们也会降低速度。
希望这可以帮助!