需要帮助优化mysql查询比较两个表

时间:2013-06-14 22:53:48

标签: mysql comparison

这是对我上一个问题link的跟进。

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

-

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

| AreaCode | Local | Created |
  • 'Local'是3位区号
  • 后面的7位数字
  • 'Created'只是一个时间戳
  • 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. 请帮我修改一下我的查询,这样就不用多久!!

1 个答案:

答案 0 :(得分:1)

回答你的问题:

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

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

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

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

  5. >

     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 */