代码之家  ›  专栏  ›  技术社区  ›  cdonner

使用Linq&SQL Server搜索匹配子字符串的最佳技术

  •  2
  • cdonner  · 技术社区  · 16 年前

    我需要在包含200000个条目的表中查找行。有些人可能不认为这个“大”,但它足够大以保证性能考虑。

    该表包含仅由数字组成的字符串。例如,用户可以输入类似于“12340-0560-78”的内容,或者部分内容,例如“0560”,我需要匹配值。

    12345678和 123405678和 0123456780等

    这些是国家药品代码(NDC),尽管有标准,但制造商通过在条形码的不同位置添加或省略零来以各种方式格式化它们。

    我首先让Linq完成这项工作,从搜索字符串中删除零和非数字字符,然后在删除列中的所有零后对该列使用contains()。这太慢了。

    所以我在表中添加了一个计算列,包含搜索列减去所有零。这更好,但由于contains(),我仍在进行表扫描。

    然后我创建了一个全文索引,但我意识到使用全文索引,我不能搜索子字符串,只能搜索单词、短语和前缀。很奇怪,但它不能解决这个问题。

    还有其他选择吗?

    2 回复  |  直到 15 年前
        1
  •  1
  •   Sebastian Seifert    16 年前

    只在计算列上创建一个简单的聚集索引怎么样?那表演可以吗?

    例如

    CREATE TABLE [dbo].[foo](
        [code] [varchar](20) NULL,
        [ccol]  AS (replace(replace([code],'-',''),' ','')
    ) ON [PRIMARY]
    

    CREATE CLUSTERED INDEX [IX_foo] ON [dbo].[foo] 
    (
        [ccol] ASC
    )
    ...
    
        2
  •  0
  •   Constantin    15 年前

    我仍然会尝试使用全文索引,但您必须以某种方式准备用于索引的文本。

    想法是创建一个独立的 ndc_suffixes 列并用以下所有后缀填充它 ndc . 也就是说 NDC = '1234567890' 这个 NDC后缀 '1234567890 234567890 34567890 ... 890 90 0' .这可能是 computed persisted column . 由于国家数据中心的长度约为10位, NDC后缀 将采取合理的存储量(它可以移动到一个单独的表无论如何)。

    然后一个 full-text prefix search 结束 NDC后缀 可用于获取子字符串匹配项。另外一张支票 ndc like '%560%' 可能有必要过滤掉假匹配,但这一个将在一组显著减少的行上运行。