Tengo una base de datos de nombres de personas que tiene (actualmente) 35 millones de filas. Necesito saber cuál es el mejor método para buscar rápidamente estos nombres. El sistema actual (no diseñado por mí) simplemente tiene indexadas las columnas del nombre y apellido y utiliza consultas "LIKE" con la opción adicional de usar SOUNDEX (aunque no estoy seguro de que esto realmente se use mucho). El rendimiento siempre ha sido un problema con este sistema, por lo que actualmente las búsquedas están limitadas a 200 resultados (lo que aún tarda demasiado en ejecutarse). Entonces, tengo algunas preguntas:SQL Server Search Nombres adecuados Índice de texto completo vs LIKE + SOUNDEX
- ¿El índice de texto completo funciona bien para los nombres propios?
- Si es así, ¿cuál es la mejor manera de consultar los nombres propios? (CONTIENE, FREETEXT, etc.)
- ¿Hay algún otro sistema (como Lucene.net) que sería mejor?
Solo como referencia, estoy usando Fluent NHibernate para acceso a datos, por lo que los métodos que funcionan serán preferidos. Estoy usando SQL Server 2008 actualmente.
EDITAR Quiero añadir que estoy muy interesado en soluciones que lidiar con cosas como nombres mal escritas habitualmente, por ejemplo, los nombres de pila 'smythe', 'Smith', así como, por ejemplo, 'Tomas', ' thomas '.
plan de consulta
|--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)
SQL para arriba:
SELECT * FROM testdb.dbo.Test WHERE LastName LIKE 'WHITE%' AND FirstName LIKE 'THOMAS%'
según el consejo del Mitch, que crea un índice de esta manera:
CREATE INDEX IX_Test_Name_DOB
ON Test (LastName ASC, FirstName ASC, BirthDate ASC)
INCLUDE (and here I list the other columns)
Mis búsquedas son ahora increíblemente rápido para mi búsqueda típica (última, primera y fecha de nacimiento).
¿También puede publicar el TSQL por favor? –