是否需要保留我已编入索引的(精确)计算搜索列?

SQB*_*SQB 4 index sql-server computed-column

我有许多列存储数据,这些数据可能包含一些用于格式化/分组的额外字符。想想电话号码和车牌号码等数据中的空白和破折号。

查询时,我们无法确定这些破折号是否存在以及在哪里存在,因此我们需要将它们从列中剥离。在查询时这样做对性能不利,所以我想为剥离的列创建一个计算列并在其上放置一个索引。

-- trimming the length down to 50 characters
-- which is the length of the original field
ALTER TABLE foo
ADD search_license_plate AS (LEFT(REPLACE(license_plate, '-', ''), 50));

CREATE INDEX ix_foo_search_license_plate ON foo(search_license_plate);
Run Code Online (Sandbox Code Playgroud)

这些计算列总是精确的,因此它们不需要因为缺乏精度而被持久化。

数据通常只输入一次并且很少被更改。从不大量使用,所以我不太关心持久化列的任何性能影响。
此外,计算列永远不会从查询中返回;它只会在查询条件中使用,通常

SELECT
   foo.id,
   foo.license_plate
FROM foo
WHERE foo.search_license_plate LIKE '%bar%';
Run Code Online (Sandbox Code Playgroud)

...虽然我不能保证SELECT *这些表上没有完成。

是否需要保留这些列?

Pau*_*ite 10

是否需要保留这些列?

通常不会,尽管有许多潜在问题需要对您的特定工作负载和客户端应用程序进行验证

主要要求(包括所有客户端的SET选项要求)列在计算列索引的文档中。例如,您还可能PERSISTED因多种原因需要添加属性,例如添加CHECKNOT NULL约束。

我强调需要在上面进行测试的原因是 SQL Server 有时会选择不在计算列上使用索引(即使持久化!)在一系列难以提前枚举的场景中 - 以及使用索引的地方是“显然”最好的策略。有关一些示例和背景,请参阅我的文章Properly Persisted Computed Columns

结果是每个查询都需要进行测试,以确保 SQL Server 可靠地选择该策略对性能很重要的索引。

您可以通过覆盖目标查询来鼓励选择索引访问方法(因此索引包含查询所需的所有列),但即使这样也不能保证。使用索引提示确实有保证,但存在风险,包括在索引不可用时抛出错误。

b-tree 索引可以帮助进行前导通配符搜索也有一个限制,如问题所示:

WHERE foo.search_license_plate LIKE '%bar%';
Run Code Online (Sandbox Code Playgroud)

充其量,这将导致对计算列上的索引进行完整扫描。您可能还对SQL Server中的Trigram 通配符字符串搜索作为替代方法感兴趣。