Mat*_*ert 5 sql-server lucene.net full-text-search fluent-nhibernate
我有一个拥有(目前)3500万行的人名的数据库.我需要知道快速搜索这些名称的最佳方法是什么.当前系统(不是我设计的),只是将索引的名字和姓氏列用于"LIKE"查询,并使用SOUNDEX的附加选项(虽然我不确定这实际上使用了多少).性能一直是该系统的一个问题,因此目前搜索限制为200个结果(运行时间仍然太长).所以,我有几个问题:
仅供参考,我使用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)
Run Code Online (Sandbox Code Playgroud)
上面的SQL:
SELECT * FROM testdb.dbo.Test WHERE LastName LIKE 'WHITE%' AND FirstName LIKE 'THOMAS%'
Run Code Online (Sandbox Code Playgroud)
根据Mitch的建议,我创建了一个这样的索引:
CREATE INDEX IX_Test_Name_DOB
ON Test (LastName ASC, FirstName ASC, BirthDate ASC)
INCLUDE (and here I list the other columns)
Run Code Online (Sandbox Code Playgroud)
我的典型搜索(最后,第一次和出生日期)的搜索速度非常快.
取决于你的LIKE查询的样子.
如果您正在搜索,LIKE '%abc%'则不能使用索引,而可以使用搜索LIKE 'abc%'索引时.此外,如果First和Last名称上的索引不"覆盖"发出的查询,则将执行密钥查找(书签查找)并显着影响性能.
您的索引是否定期重建?
你有一个示例查询计划吗?
更新:查询的覆盖索引是可用于执行WHERE条件的索引,并且还具有满足查询其余部分所需的所有列,例如SELECT列列表.
更新:即使您创建了一个复合索引(Lastname, Firstname) (因为lastname应该更具选择性),仍然需要在表聚簇索引中查找所有其他列('*'列列表).
| 归档时间: |
|
| 查看次数: |
2368 次 |
| 最近记录: |