BLOB 如何存储在索引视图中?
How is BLOB stored in an indexed view?
问题
假设我在包含 varbinary(max)
列的 table 上创建索引视图,二进制内容是否会物理复制到索引视图的 B 树中,或者原始字段是否只是 "referenced" 不知何故,没有物理复制他们的内容?
换句话说,如果我对包含 BLOB 的 table 创建索引视图,是否会复制 BLOB 所需的存储空间?
更多详情
当对二进制数据使用全文索引时,例如 varbinary(max)
,我们需要一个额外的 "filter type" 列来指定如何从该二进制数据中提取文本以便对其进行索引,像这样:
CREATE FULLTEXT INDEX ON <table or indexed view> (
<data column> TYPE COLUMN <type column>
)
...
在我的特定情况下,这些字段位于不同的 table 中,我正在尝试使用索引视图将它们连接在一起,以便它们可以在全文索引中使用。
当然,我可以将类型字段复制到 BLOB table 并手动维护它(保持与原始同步),但我想知道是否可以让 DBMS 自动为我做这件事,这会更好除非在存储方面要付出高昂的代价。
此外,将这两个 table 合并为一个本身会产生负面影响,这里不再赘述...
will that duplicate the storage needed for BLOBs?
是的。索引视图将有自己的副本。
你可以从
看到这个
CREATE TABLE dbo.T1
(
ID INT IDENTITY PRIMARY KEY,
Blob VARBINARY(MAX)
);
DECLARE @vb VARBINARY(MAX) = CAST(REPLICATE(CAST('ABC' AS VARCHAR(MAX)), 1000000) AS VARBINARY(MAX));
INSERT INTO dbo.T1
VALUES (@vb),
(@vb),
(@vb);
GO
CREATE VIEW dbo.V1
WITH SCHEMABINDING
AS
SELECT ID,
Blob
FROM dbo.T1
GO
CREATE UNIQUE CLUSTERED INDEX IX
ON dbo.V1(ID)
SELECT o.NAME AS object_name,
p.index_id,
au.type_desc AS allocation_type,
au.data_pages,
partition_number,
au.total_pages,
au.used_pages
FROM sys.allocation_units AS au
JOIN sys.partitions AS p
ON au.container_id = p.partition_id
JOIN sys.objects AS o
ON p.object_id = o.object_id
WHERE o.object_id IN ( OBJECT_ID('dbo.V1'), OBJECT_ID('dbo.T1') )
哪个returns
+-------------+----------+-----------------+------------+------------------+-------------+------------+
| object_name | index_id | allocation_type | data_pages | partition_number | total_pages | used_pages |
+-------------+----------+-----------------+------------+------------------+-------------+------------+
| T1 | 1 | IN_ROW_DATA | 1 | 1 | 2 | 2 |
| T1 | 1 | LOB_DATA | 0 | 1 | 1129 | 1124 |
| V1 | 1 | IN_ROW_DATA | 1 | 1 | 2 | 2 |
| V1 | 1 | LOB_DATA | 0 | 1 | 1129 | 1124 |
+-------------+----------+-----------------+------------+------------------+-------------+------------+
问题
假设我在包含 varbinary(max)
列的 table 上创建索引视图,二进制内容是否会物理复制到索引视图的 B 树中,或者原始字段是否只是 "referenced" 不知何故,没有物理复制他们的内容?
换句话说,如果我对包含 BLOB 的 table 创建索引视图,是否会复制 BLOB 所需的存储空间?
更多详情
当对二进制数据使用全文索引时,例如 varbinary(max)
,我们需要一个额外的 "filter type" 列来指定如何从该二进制数据中提取文本以便对其进行索引,像这样:
CREATE FULLTEXT INDEX ON <table or indexed view> (
<data column> TYPE COLUMN <type column>
)
...
在我的特定情况下,这些字段位于不同的 table 中,我正在尝试使用索引视图将它们连接在一起,以便它们可以在全文索引中使用。
当然,我可以将类型字段复制到 BLOB table 并手动维护它(保持与原始同步),但我想知道是否可以让 DBMS 自动为我做这件事,这会更好除非在存储方面要付出高昂的代价。
此外,将这两个 table 合并为一个本身会产生负面影响,这里不再赘述...
will that duplicate the storage needed for BLOBs?
是的。索引视图将有自己的副本。
你可以从
看到这个CREATE TABLE dbo.T1
(
ID INT IDENTITY PRIMARY KEY,
Blob VARBINARY(MAX)
);
DECLARE @vb VARBINARY(MAX) = CAST(REPLICATE(CAST('ABC' AS VARCHAR(MAX)), 1000000) AS VARBINARY(MAX));
INSERT INTO dbo.T1
VALUES (@vb),
(@vb),
(@vb);
GO
CREATE VIEW dbo.V1
WITH SCHEMABINDING
AS
SELECT ID,
Blob
FROM dbo.T1
GO
CREATE UNIQUE CLUSTERED INDEX IX
ON dbo.V1(ID)
SELECT o.NAME AS object_name,
p.index_id,
au.type_desc AS allocation_type,
au.data_pages,
partition_number,
au.total_pages,
au.used_pages
FROM sys.allocation_units AS au
JOIN sys.partitions AS p
ON au.container_id = p.partition_id
JOIN sys.objects AS o
ON p.object_id = o.object_id
WHERE o.object_id IN ( OBJECT_ID('dbo.V1'), OBJECT_ID('dbo.T1') )
哪个returns
+-------------+----------+-----------------+------------+------------------+-------------+------------+
| object_name | index_id | allocation_type | data_pages | partition_number | total_pages | used_pages |
+-------------+----------+-----------------+------------+------------------+-------------+------------+
| T1 | 1 | IN_ROW_DATA | 1 | 1 | 2 | 2 |
| T1 | 1 | LOB_DATA | 0 | 1 | 1129 | 1124 |
| V1 | 1 | IN_ROW_DATA | 1 | 1 | 2 | 2 |
| V1 | 1 | LOB_DATA | 0 | 1 | 1129 | 1124 |
+-------------+----------+-----------------+------------+------------------+-------------+------------+