Sql server SQL Server搜索专有名称全文索引vs LIKE+;SOUNDEX

Sql server SQL Server搜索专有名称全文索引vs LIKE+;SOUNDEX,sql-server,fluent-nhibernate,full-text-search,lucene.net,Sql Server,Fluent Nhibernate,Full Text Search,Lucene.net,我有一个人名数据库,目前有3500万行。我需要知道快速搜索这些名字的最佳方法是什么。当前的系统(不是由我设计的),只是将名字和姓氏列编入索引,并使用“LIKE”查询,另外还可以选择使用SOUNDEX(尽管我不确定这是否实际使用得太多)。性能一直是这个系统的一个问题,因此目前搜索限制为200个结果(运行时间仍然太长)。因此,我有几个问题: 全文索引对专有名称有效吗 如果是,查询专有名称的最佳方式是什么?(包含、自由文本等) 有没有其他更好的系统(比如Lucene.net) 仅供参考,我正在使用Fl

我有一个人名数据库,目前有3500万行。我需要知道快速搜索这些名字的最佳方法是什么。当前的系统(不是由我设计的),只是将名字和姓氏列编入索引,并使用“LIKE”查询,另外还可以选择使用SOUNDEX(尽管我不确定这是否实际使用得太多)。性能一直是这个系统的一个问题,因此目前搜索限制为200个结果(运行时间仍然太长)。因此,我有几个问题:

  • 全文索引对专有名称有效吗
  • 如果是,查询专有名称的最佳方式是什么?(包含、自由文本等)
  • 有没有其他更好的系统(比如Lucene.net)
  • 仅供参考,我正在使用Fluent NHibernate进行数据访问,因此首选能够与之协同工作的方法。我目前正在使用SQL Server 2008

    编辑我想补充一点,我对处理常见拼写错误的名字(如“smythe”、“smith”)以及名字(如“tomas”、“thomas”)的解决方案非常感兴趣

    查询计划

      |--Parallelism(Gather Streams)
           |--Nested Loops(Inner Join, OUTER REFERENCES:([testdb].[dbo].[Test].[Id], [Expr1004]) OPTIMIZED WITH UNORDERED PREFETCH)
                |--Hash Match(Inner Join, HASH:([testdb].[dbo].[Test].[Id])=([testdb].[dbo].[Test].[Id]))
                |    |--Bitmap(HASH:([testdb].[dbo].[Test].[Id]), DEFINE:([Bitmap1003]))
                |    |    |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([testdb].[dbo].[Test].[Id]))
                |    |         |--Index Seek(OBJECT:([testdb].[dbo].[Test].[IX_Test_LastName]), SEEK:([testdb].[dbo].[Test].[LastName] >= 'WHITDþ' AND [testdb].[dbo].[Test].[LastName] < 'WHITF'),  WHERE:([testdb].[dbo].[Test].[LastName] like 'WHITE%') ORDERED FORWARD)
                |    |--Parallelism(Repartition Streams, Hash Partitioning, PARTITION COLUMNS:([testdb].[dbo].[Test].[Id]))
                |         |--Index Seek(OBJECT:([testdb].[dbo].[Test].[IX_Test_FirstName]), SEEK:([testdb].[dbo].[Test].[FirstName] >= 'THOMARþ' AND [testdb].[dbo].[Test].[FirstName] < 'THOMAT'),  WHERE:([testdb].[dbo].[Test].[FirstName] like 'THOMAS%' AND PROBE([Bitmap1003],[testdb].[dbo].[Test].[Id],N'[IN ROW]')) ORDERED FORWARD)
                |--Clustered Index Seek(OBJECT:([testdb].[dbo].[Test].[PK__TEST__3214EC073B95D2F1]), SEEK:([testdb].[dbo].[Test].[Id]=[testdb].[dbo].[Test].[Id]) LOOKUP ORDERED FORWARD)
    
    根据Mitch的建议,我创建了如下索引:

    CREATE INDEX IX_Test_Name_DOB
    ON Test (LastName ASC, FirstName ASC, BirthDate ASC)
    INCLUDE (and here I list the other columns)
    

    对于我的典型搜索(last、first和birth date),我的搜索现在非常快。

    如果在“名字”和“姓氏”列上创建索引,那么使用LIKE的精确匹配搜索和前缀搜索将变得非常快

    (在中,“如果LIKE的参数是一个不以通配符开头的常量字符串,则索引也可用于LIKE比较。”我认为MS SQL有类似的规则,但请查看MS SQL文档以确定。)


    要加快SoundEx搜索,请存储新列的名字和姓氏的SoundEx版本,并在这些列上创建索引。

    取决于您喜欢的查询的外观

    如果您正在搜索像“%abc%”这样的
    则不能使用索引,而在搜索像“abc%”这样的
    时,可以使用索引。此外,如果名字和姓氏上的索引未“覆盖”发出的查询,则将执行键查找(书签查找),并显著影响性能

    你的索引是否定期重建

    您有一个示例查询计划吗

    更新:查询的覆盖索引可用于执行WHERE条件,并具有满足查询其余部分(如选择列列表)所需的所有列


    更新:即使您在
    (Lastname,Firstname)
    上创建了一个复合索引(因为Lastname应该更具选择性),仍然需要在表聚集索引中查找所有其他列(“*”列列表)。

    我不太喜欢soundex。我认为新的算法迭代会更好,但是你把英语中的每个单词都散列成一个相当小的散列。随着时间的推移,这往往会产生大量错误匹配。我读过那个变音,它的后继双变音更好,但我没有直接的经验


    米奇对
    之类的的报道相当全面,所以我不打算重复了。

    索引将定期重建,可能每周重建一次。我正在以每天大约5000条的速度添加记录。哈,看起来当前系统根本没有使用“like”,显然太慢了。所以,我认为“abc%”应该是一种改进。你说的“覆盖”是什么意思?这真的很有帮助,米奇。我正在为您准备一个示例查询计划。那么,我应该创建一个包含我感兴趣的所有列的索引吗?我已经添加了查询执行计划。马修·塔尔伯特:嗯,这是一种权衡,取决于几个因素。宽索引通常不是一个好主意。您可以使用SQL Server 2005及以后版本的“包含部分创建索引定义”来创建覆盖索引。您还可以发布TSQL吗?谢谢您提供有关soundex的信息。
    CREATE INDEX IX_Test_Name_DOB
    ON Test (LastName ASC, FirstName ASC, BirthDate ASC)
    INCLUDE (and here I list the other columns)