7

我在一个网站上工作,该网站销售让我们说的东西并提供“供应商搜索”。在此搜索中,您输入您的城市、邮政编码、地区和距离(以公里或英里为单位),然后该网站会为您提供供应商列表。

为此,我有一个供应商数据库。在保存这些供应商的表格中,您输入他们的完整地址,当您单击保存按钮时,会向谷歌地图发出请求以获取他们的纬度和经度。

当有人进行搜索时,我会查看存储所有搜索词及其 lat/lng 的表格。这张桌子看起来像

+--------+-------+------+
| term   | lat   | lng  |
+--------+-------+------+

所以第一个查询很简单

select lat, lng from my_search_table where term = "the term"

如果我找到结果,然后我会用一种很好的方法搜索访问者想要的范围内的所有供应商,并将结果打印在地图上。

如果我没有找到结果,我会使用 levenshtein 函数进行搜索,因为人们写 bruxelle 或 bruxeles 而不是 bruxelles 很常见,我不想一直请求谷歌地图(我也有一个“在我的表中搜索了多少次”列以获取一些统计信息)

所以我请求没有 where 子句的 my_search_time 并遍历所有结果以获得最小的 levensthein 距离。如果最小的结果大于 2,我从谷歌地图请求坐标。

这是我的问题。对于某些国家/地区(我们在世界各地有多个站点),my_search_table 有 15-20k+ 个条目......并且 php(真的)不喜欢循环使用这些数据(我完全理解)并且我的请求属于 php 超时. 我可以增加这个超时时间,但几个月后问题会一样。

所以我尝试了一个 levensthein MySQL 函数(在stackoverflow上找到),但它也很慢。

所以我的问题是“即使在非常大的数据集上,有没有办法让这个搜索快速?”

4

3 回答 3

4

我的建议基于三点:

  • 首先,您的数据集很大。这意味着 - 它:大到足以拒绝“全选”+“levenshtein()在 PHP 应用程序中运行”的想法
  • 其次,您可以控制您的数据库。所以你可以调整一些架构相关的东西
  • 最后,SELECT查询的性能是最重要的,而添加新数据的性能并不重要

问题是您不能执行快速的 levenshtein 搜索,因为levenshtein 本身非常慢。我的意思是,计算 levenshtein 距离是一件很慢的事情。因此,您将无法仅通过“智能搜索”解决问题。你必须准备一些数据。

可能的解决方案是:创建一些组索引并在添加/更新数据期间分配它。这意味着 - 您将存储额外的列,该列将存储一些哈希(例如数字)。添加新数据时,您将:

  • 使用 levenshtein 距离执行搜索(因为您可以使用您的应用程序或您已经(已经提到)在表中的所有记录上针对插入数据的功能
  • 将新行的组索引设置为上一步中找到的行所具有的索引值。
  • 如果没有找到,设置一些新的组索引值(它是第一行并且还没有类似的行) - 这将不同于表中已经存在的任何组索引值

要搜索所需的行,您只需选择具有相同组索引值的行。这意味着:您的选择查询将非常快。但是 - 是的,这将在添加/更改数据时造成极其巨大的开销。因此,它不适用于更新/插入的性能很重要的情况。

于 2014-04-03T09:12:15.477 回答
1

你可以试试 MySQL 函数SOUNDS LIKE

SELECT lat, lng FROM my_search_table WHERE term SOUNDS LIKE "the term"
于 2013-03-02T09:17:37.450 回答
0

您可以使用 kd-tree 或三叉树来加快搜索速度。这个想法是使用二进制搜索。

于 2013-03-02T11:27:01.927 回答