在阅读我的 70-433 试卷时,我想到了一些我认为不起作用的东西,但我相信它确实有效。这段话是这样写的:
该列还必须标记为PERSISTED,这意味着 SQL Server 将计算列的表达式的结果物理存储在数据行中,而不是每次在查询中引用时计算它。
由此我明白了两件事:
读完后,我觉得这有点奇怪,因为我在以前的项目中设法在非持久化列上创建了索引。
如何为未持久化的东西创建索引,从长远来看这是否有害?
为了证明这一点,我运行了以下 SQL 语句:
CREATE TABLE testTable
(
ID INT IDENTITY(1,1) PRIMARY KEY,
telephone VARCHAR(14),
c_areaCode AS (SUBSTRING(telephone,0,5)),
cp_areaCode AS (SUBSTRING(telephone,0,5)) PERSISTED
)
INSERT INTO testTable VALUES('09823 000000');
INSERT INTO testTable VALUES('09824 000000');
INSERT INTO testTable VALUES('09825 000000');
CREATE NONCLUSTERED INDEX IX_NotPersisted ON testTable(c_areaCode);
CREATE NONCLUSTERED INDEX IX_Persisted ON testTable(cp_areaCode);
Run Code Online (Sandbox Code Playgroud)
然后运行以下查询:
DBCC FREEPROCCACHE
DBCC FREESYSTEMCACHE('ALL');
DBCC DROPCLEANBUFFERS
GO
SELECT cp_areaCode FROM testTable;
GO
SELECT c_areaCode FROM testTable;
Run Code Online (Sandbox Code Playgroud)
查看上述代码的查询计划后,我可以看到两个选择查询都使用了非持久化索引。又如何?
2.因为计算列没有存储任何东西,我假设不能为该列创建索引。
这个假设是不正确的 -任何一种都可以被索引。在任何一种情况下,计算列都必须是确定性的,但是当计算列被持久化时,计算也精确的要求就放宽了(即它可以涉及浮点运算)。
如何为未持久化的东西创建索引,从长远来看这是否有害?
在任何一种情况下,函数的结果都在索引中“持久化” ——唯一的区别是它是否在表中持久化。