1

我有一个带有 2 个表的 MySQL 数据库:

表 A:

  • 数字
  • 地点

表 B:

  • 调用代码
  • 区号
  • 地点

最初,我在表 A 中有大约 60,000 个条目,该表的开头位置列是空的。在表 BI 中有大约 250,000 多个条目,其中包含许多区号、呼叫代码 (1, 011) 及其各自在世界上的位置。我想要的是一种用数字位置填充表 A 的位置列的快速方法。

因此,例如,如果表 A 中的第一个条目是 (17324765600, null) 我想通过表 B 读取并获取该数字的位置。现在我通过这个查询得到一个号码的位置:

SELECT b.location
FROM 
  tableB b
  LEFT JOIN tableA a
     ON a.number LIKE CONCAT(b.calling_code, b.code, '%')
ORDER BY CHAR_LENGTH(b.code) DESC
LIMIT 1;

这给了我正确的位置(即使我怀疑它会失败..)。问题在于性能方面,这种方法是行不通的。如果我遍历所有 50k 数字

更新 1

请允许我放一些带有预期输出的示例数据:示例表 A:

号码位置
17324765600 空
01134933638950 空
0114008203800 空
…60k 记录 + 目前..

样品表 B:

call_code 代码位置
1 7324765 美国-新泽西
011 34933 西班牙
011 400820 中国
…目前有 250,000 多条记录

处理后的预期输出:表A:

号码位置
17324765600 美国-新泽西
01134933638950西班牙
0114008203800 中国

我想出的最好的是以下更新声明:

UPDATE tableA a JOIN tableB b ON a.location LIKE CONCAT(b.calling_code, b.code, '%') SET a.location = b.location

当然,在这里我不确定它是否总是返回代码的最长前缀,例如,如果在上表中有另一个以 73247XX 开头的代码,假设代码是针对爱荷华州的(仅作为示例)。我是不确定查询是否总是返回最长的代码,所以在这里我也需要帮助。

让我知道样品是否有帮助。

.SQL 用于数据库结构: 下载

更新 2:

我正在考虑通过以下方式执行此操作:

在将数据插入表 AI 之前,我正在考虑将表 B 导出到 CSV 并按区号对其进行排序,这样我可以有 2 个指针,一个用于表 A 的条目数组,一个用于 csv,均按区号排序这样我就可以进行一种并行搜索并在 PHP 上填充条目的位置,而不必在 MySQL 中执行此操作。

让我知道这种方法是否是一个更好的选择,如果是的话,我会对其进行测试并发布答案。

4

3 回答 3

0

如果您想要所有位置,则需要删除LIMIT

SELECT b.location
FROM 
  tableB b
  LEFT JOIN tableA a
     ON a.number LIKE CONCAT(b.calling_code, b.code, '%')
ORDER BY CHAR_LENGTH(b.code);

如果您希望相同的位置名称不应该出现两次,那么您需要使用GROUP BY

SELECT b.location
FROM 
  tableB b
  LEFT JOIN tableA a
     ON a.number LIKE CONCAT(b.calling_code, b.code, '%')
GROUP BY b.location  ORDER BY CHAR_LENGTH(b.code) ;
于 2015-07-03T19:26:26.420 回答
0

你有一个只有 250000 条记录的连接,它没有那么紧张。您应该为搜索列和fine tune your mysql server. A good indexing & server variables wellto set 将轻松解决您的问题。优化您的查询。通常,当我们有很多连接和很多字符串比较时,它会产生问题。

我认为您需要这样的查询-

UPDATE a SET a.location = ( 
                            SELECT location from b 
                            WHERE a.number LIKE CONCAT(b.calling_code, b.area_code, '%') 
                            ORDER BY LENGTH(CONCAT(b.calling_code, b.area_code, '%')) desc 
                            limit 1
                          );
于 2015-07-03T19:36:32.840 回答
0

由于没有收到任何明确的答复,我决定采用以下方法:

在此过程之前,我准备了 2 个新表,一个国家代码表和一个州代码表(因为如果数字在美国境内,我还需要知道州)。两个表都有:国家、州、调用代码、代码……</p>

至于这两张表,我将所有带有前缀的数字分解并按区号分组,因此我没有使用完整的 6 个数字来识别国家/州,而是按前 3 个数字分组它们,如果代码在美国境内或不是,因此有 2 张桌子。

通过这些修改,我能够将 250,000 + 行的表分解为只有大约 300 行(每个表)。

在此之后,我将按照以下步骤操作:

  1. 我得到电话号码列表
  2. 我首先执行一个与我发布的查询非常相似的查询,以更新属于 country_code 表的所有数字
  3. 然后我更新仍然没有使用 state_code 表分配位置的行
  4. 我必须放置某种 cron 以便每 x 时间完成一次,以避免拥有大量手机。

这可能不是最好的方法,但是对于目前已有的 50k 数字,我能够(手动执行查询并进行更多抛光)将其缩短到大约 10 秒,每 x 时间执行一次(这将允许对少于 10k 的数字执行此过程)将使此过程顺利进行。

我会将其标记为答案,但如果其他人神奇地提出了更好的答案,我将确保更新它。

分而治之!

于 2015-07-08T17:58:19.973 回答