SQL Server - 计算列的索引?

Sql*_*yan 16 sql-server indexing calculated-columns sql-server-2008

我加入一个表几十个不同的时间,每次,我根据其中一列的SUBSTRING结果加入(或过滤)(它是一个字符串,但左边用零填充,我不是'关心最后四位数).因此,即使此列已编制索引并且我的查询将使用索引,它也会进行表扫描,因为SUBSTRING本身未编入索引,因此SQL Server必须在加入之前为每一行计算它.

我正在寻找有关如何加快这一过程的任何想法.目前,在表上有一个视图(它是一个"SELECT*FROM",只是为了给表一个友好的名称),我正在考虑在计算的视图中添加一列,然后对其进行索引.不过,我对其他建议持开放态度 - 任何想法?

更多细节: 我应该首先分享这个.该表从我们的计费系统接收复制,因此编辑基础表以添加计算列不是一种选择.必须将任何计算列添加到表上的视图中.此外,前导零并不总是前导零 - 它们有时是我不感兴趣的其他数据.我认为真正的问题是" 如何在VARCHAR列的中间加入数据同时还可以使用一个索引?全文搜索? "

澄清我的例子 我正在简化,但实际上,假设我正在尝试使用以下值在列中查找值:

00000012345MoreStuff
00000012345Whatever
19834212345
Houses12345837443GGD
00000023456MoreStuff
Run Code Online (Sandbox Code Playgroud)

我对SUBSTRING(7,5)="12345"的行感兴趣,所以我想要1-4行,但不是第5行.我建议的是在我的"SELECT*"视图中添加一列在其中包含此子字符串,然后根据该索引进行索引.那更有意义吗?

Qua*_*noi 13

假设您有以这种格式的字段:

00Data0007
000000Data0011
0000Data0015
Run Code Online (Sandbox Code Playgroud)

,你可以做到以下几点:

  • 创建计算列: ndata AS RIGHT(REVERSE(data), LEN(data) - 4)

    这会将您的列转换为以下内容:

    ataD00
    ataD000000
    ataD0000
    
    Run Code Online (Sandbox Code Playgroud)
  • 在该列上创建索引

  • 发出此查询以搜索字符串Data:

    SELECT  *
    FROM    mytable
    WHERE   ndata LIKE N'ataD%'
            AND SUBSTRING(ndata, LEN(N'ataD') + 1, LEN(ndata)) = REPLICATE('0', LEN(ndata) - LEN('ataD'))
    
    Run Code Online (Sandbox Code Playgroud)

    第一个条件将使用索引进行粗略过滤.

    第二个将确保所有前导字符(成为计算列中的尾随字符)只是零.

有关性能详情,请参阅我的博客中的此条目:

更新

如果您只想在SUBSTRING不更改架构的情况下启用索引,则可以选择创建视图.

CREATE VIEW v_substring75
WITH SCHEMABINDING
AS
SELECT  s.id, s.data, SUBSTRING(data, 7, 5) AS substring75
FROM    mytable

CREATE UNIQUE CLUSTERED INDEX UX_substring75_substring_id ON (substring75, id)

SELECT  id, data
FROM    v_substring75
WHERE   substring75 = '12345'
Run Code Online (Sandbox Code Playgroud)


pjp*_*pjp 6

计算列添加到表中并在此列上创建索引.

ALTER TABLE MyTable
Add Column CodeHead As LEFT(Code,Len(Code)-4)
Run Code Online (Sandbox Code Playgroud)

然后在此创建一个索引.

CREATE INDEX CodeHeadIdx ON MyTable.CodeHead
Run Code Online (Sandbox Code Playgroud)