0

这是对我之前的问题链接的一种跟进。

一段时间过去了,所以我不确定是否需要更新那个或创建一个新的,特别是因为我的问题的参数发生了一些变化。

--

我有一个大的(简单的)电话号码表(> 500 万并且还在增长)。该表设置如下:

| AreaCode | Local | Created |
  • “本地”是 3 位区号后面的 7 位数字
  • “创建”只是一个时间戳
  • AreaCode 和 Local 都被索引
  • 我曾经有一个 ID 列作为我的主键,但在我对表进行分区时将其删除。我在 AreaCode 上按范围设置了 10 个分区(<100、<200、<300、~<999)

我正在上传数字的 csv 文件(最多 250k 行),通过 PHP 清理和清理输入,然后创建一个临时表并将数据插入其中。

在这之后,我遇到了很多麻烦。对于较小的数据大小(10k-25k 行),我真的没有任何问题。但是,当我尝试将包含 250k+ 行的临时表与我的主数据库进行比较时,需要的时间非常长。

我已经尝试了以下 2 个查询,但其中任何一个都不太走运。

使用内连接

SELECT a.* FROM master_table a
INNER JOIN temp_table b
ON a.AreaCode = b.AreaCode
AND a.Local = b.Local;

我在一个网站上找到了这个建议并尝试了它

SELECT b.* FROM temp_table b
WHERE b.AreaCode
IN (
    SELECT a.AreaCode
    FROM master_table a
    WHERE a.AreaCode = b.AreaCode
    AND a.Local = b.Local
);

我为长长的问题道歉,但我对 mysql 的掌握很弱。

  1. 我是否因为没有主键和/或唯一键而犯了错误?由于每个电话号码都是唯一的,我不确定拥有 ID 列是否对我有利。
  2. 我对我的主表进行分区是正确的还是这让我放慢了速度?
  3. 我的 AreaCode 和 Local 列上有索引。当我创建临时表时,我是否也应该在相同的列上创建索引?
  4. 请帮我解决我的查询,这样就不会花这么长时间了!!
4

1 回答 1

1

要回答您的问题:

  1. 我看不到您如何使用当前索引强制执行唯一性。您可以有一个复合主索引areaCodelocal强制执行此唯一性。我肯定会有某种主键。我会质疑您是否需要查询local而不areaCode确定是否需要单独的索引。就个人而言,如果我要在其他表中引用该数据(例如,如果我想将电话号码与用户或其他东西相关联),我可能会在这两个字段上使用自动增量主键和复合唯一索引,因为我发现它较少使用单个键时关联表很麻烦。

  2. 500 万行并不是一张那么大的表。可能为时过早进行分区。此外,根据数据库中不同区号的比率以及这些区号的访问模式,这可能不是一个好的分区方案。

  3. 如果您要使用磁盘上的临时表并加入这些大型数据集,则需要提供索引。

  4. 你有两个不同的查询在这里做两个不同的事情。如果最终目的是将此数据插入到主表数据中,我不明白您为什么要尝试进行联接。你可以简单地按照以下方式做一些事情:

>

 INSERT INTO master_table (`areaCode`, `local`)
 SELECT SELECT `areaCode`, `local`
 FROM temp_table
 ON DUPLICATE KEY UPDATE UPDATE `created` = NOW() /* You can add this line is you want to update the time stamp */
于 2013-06-14T23:12:53.467 回答