1

我有一个 mysql 表,其中包含 4000 万条记录,这些记录由我无法控制的进程填充。每个月只添加一次数据。此表需要通过名称列进行搜索。但名称列包含格式为“Last First Middle”的全名。

在 sphinx.conf 中,我有

sql_query = SELECT Id, OwnersName,
substring_index(substring_index(OwnersName,' ',2),' ',-1) as firstname, 
substring_index(OwnersName,' ',2) as lastname
FROM table1

如何使用 sphinx 搜索按名字和/或姓氏搜索?我希望能够仅在名字中搜索“Smith”吗?

4

4 回答 4

4

SQL 查询中的每行函数对于可能变得很大的表来说总是一个坏主意。如果要搜索列的一部分,则应将其提取到自己的列中并编制索引。

我建议,如果您对架构拥有权力(与填充过程相反),则插入名为 OwnersFirstName 和 OwnersLastName 的新列以及从 OwnersName 提取相关信息并适当填充新列的更新/插入触发器。

这意味着仅在更改行时才会计算出名字的开销,而不是每次运行查询时。那是做这件事的正确时机。

然后你的查询变得非常快。而且,是的,这打破了 3NF,但大多数人没有意识到出于性能原因这样做是可以的,前提是您了解后果。而且,由于新列由触发器控制,因此引起关注的数据重复是“干净的”。

人们对数据库的大多数问题是他们的查询速度。浪费一点磁盘空间来获得大量的性能改进通常是可以的。

如果您对架构完全没有权力,另一种可能性是使用“正确”架构创建您自己的数据库,并定期从真实数据库中填充它。然后查询你的。但是,这可能涉及每月进行相当多的数据传输,因此如果允许,第一个选择是更好的选择。

于 2009-08-08T11:51:29.327 回答
1

从其他答案来看,我可能错过了一些东西......但是要将 Sphinx 中的搜索限制为特定字段,请确保您使用的是扩展(或扩展2)匹配模式,然后使用以下查询字符串:@firstname Smith.

于 2009-08-10T21:47:03.700 回答
0

您可以使用 substring 来获取要在其中搜索的字段部分,但这会减慢该过程。查询不能使用任何类型的索引来进行比较,所以它必须触及表中的每条记录。

最好不要在同一个字段中存储多个值,而是将名称组件放在三个单独的字段中。当您在一个字段中存储多个值时,访问数据几乎总是会出现一些问题。我在不同的论坛上一遍又一遍地看到这个......

于 2009-08-08T11:52:12.413 回答
0

这是一个棘手的问题,因为全名可以包含前缀、后缀、中间名和没有中间名、有和没有连字符的复合名字和姓氏等。没有合理的方法可以 100% 可靠地做到这一点

于 2009-08-08T11:55:28.023 回答