这是对我之前的问题link的后续。
一段时间过去了,所以我不确定是否需要更新那个或创建一个新的,尤其是因为我的问题的参数已经改变了一点。
-
我有一张很大的(简单的)电话号码表(> 500万并且还在不断增长)。该表的设置如下:
| AreaCode | Local | Created |
“本地”是3位区号之后的7位数字
“已创建”只是一个时间戳记
AreaCode和Local都已建立索引
我曾经有一个ID列作为主键,但是在对表进行分区时将其删除。我在AreaCode上按范围设置了10个分区(
我正在上传数字的csv文件(最多25万行),通过PHP清理和清理输入,然后创建一个临时表并将数据插入其中。
在这之后,我遇到了很多麻烦。对于较小的数据大小(1万至25,000行),我真的没有任何问题。但是,当我尝试将包含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的掌握程度很弱。
我没有主键和/或唯一键是否犯了错误?由于每个电话号码都是唯一的,因此我不确定拥有ID列是否会使我受益。
我应该对我的主表进行分区吗,还是让我慢下来?
我在AreaCode和Local列上有索引。创建临时表时,是否也应该在同一列上创建索引?
请帮我解决我的问题,以免花费很长时间!
最佳答案
要回答您的问题:
我看不到您如何在当前索引中实施唯一性。您可以在areaCode
和local
上使用复合主索引来强制执行此唯一性。我肯定会有某种主键。我会问您是否需要查询不带local
的areaCode
以确定是否需要单个索引。就个人而言,如果我要引用其他表中的数据(例如,如果我想将电话号码与用户等联系起来),我会在这两个字段上使用自动递增主键和复合唯一索引,因为我发现它较少使用单个键关联表很麻烦。
500万行不是一个表那么大。可能为时过早。另外,根据数据库中不同区域代码的比率以及这些代码的访问模式,这可能不是一个好的分区方案。
如果要使用磁盘上的临时表并要与这些大数据集联接,则需要提供索引。
您有两个不同的查询,在这里执行两个不同的操作。如果目的是最终将此数据插入到主表数据中,那么我根本不明白为什么要尝试进行联接。您可以按照以下方式做一些事情:
>
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 */