存储和索引varchar列,其中大多数值将是数字

时间:2017-03-03 20:39:22

标签: sql-server sql-server-2008 indexing

我有两张桌子。这是在SQL Server 2008 R2中:

dbo.Source:SourceId(int),SourceName(varchar(10))

SourceId|SourceName
1|Source1
2|Source2
3|Source3

dbo.SourceIdentifiers:Id(int),SourceId(int)外键Source.SourceId,SourceIdentifier varchar(30)

Id|SourceId|SourceIdentifier
1|1|123
2|1|456
3|2|789
4|2|789
5|2|789
6|3|ABC

正如您所看到的,我从多个来源接收数据,大多数来源都有一个数字作为标识符,但其中一些也有字符。所以我的SourceIdentifier列需要是一个varchar。

通常会根据SourceIdentifier查询表。我可以拥有多达1亿个唯一的源标识符。我希望查询超快。我有几个问题:

  1. 如果我在SourceIdentifier列上添加索引,这是个好主意吗?由于该列有大约75%的整数存储为varchars。
  2. 如果没有,可能是替代方法。创建两个源标识符表,一个用于整数源,一个用于字符源?
  3. 谢谢!

2 个答案:

答案 0 :(得分:1)

我认为你可以使用选项1)即:在SourceIdentifer列上创建非聚簇索引,如果需要从查询中获取SourceId以避免密钥查找,请确保使其覆盖索引。

2)方法的问题是你的连接会变得复杂,这会影响性能。

答案 1 :(得分:1)

如果有意义,我会将SourceIdentifier编入索引。但是,如果您担心,可以执行以下操作:

  1. 创建一个用户定义的函数,用于解析字符串并返回 如果可能的话,整数表示,否则为NULL。
  2. 向表中添加PERSISTED计算列 SourceIdentifierInteger被定义为该结果 SourceIdentifier
  3. 的用户定义函数
  4. 在SourceIdentifierInteger WHERE SourceIdentifierInteger IS NOT NULL上添加过滤后的索引。
  5. 当您查询时,如果是整数值,请在WHERE上构建SourceIdentifierInteger子句,否则在SourceIdentifier列上构建

    我不知道这会仅仅为SourceIdentifier列编制索引而获得任何性能提升,但这是一个选项。