【发布时间】:2013-06-15 07:12:53
【问题描述】:
这是对我之前的问题link 的跟进。
一段时间过去了,所以我不确定是否需要更新那个或创建一个新的,特别是因为我的问题的参数发生了一些变化。
--
我有一个大型(简单)电话号码表(> 500 万并且还在增长)。表设置如下:
| AreaCode | Local | Created |
- 'Local' 是 3 位区号后面的 7 位数字
- “已创建”只是一个时间戳
- AreaCode 和 Local 均已编入索引
- 我曾经有一个 ID 列作为我的主键,但在我对表进行分区时删除了它。我在 AreaCode (
我正在上传数字的 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 的掌握很弱。
- 我是否因为没有主键和/或唯一键而犯了错误?由于每个电话号码都是唯一的,我不确定拥有 ID 列是否对我有好处。
- 我对我的主表进行分区是正确的还是这会减慢我的速度?
- 我的 AreaCode 和 Local 列上有索引。当我创建临时表时,我是否也应该在其中的相同列上创建索引?
- 请帮我解决我的查询,这样就不会花这么长时间了!!
【问题讨论】:
-
您是否查看了查询计划输出以查看您的两个查询是否都在进行表扫描?那将是我要看的第一件事。另外,我会在临时表上放置一个索引,因为如果你不这样做,你实际上是在子查询期间强制进行表扫描。
-
每列有单独的索引,还是
(AreaCode, Local)有复合索引? -
@TimoGeusch 那会使用解释吗?我昨天确实拉了它,我现在正试图理解它,tbh。和 ty 用于澄清临时表上的索引。我一直在这样做,但不确定是否应该这样做。
-
@Barmar 我正在使用单独的索引。这不是要走的路吗?
-
优化连接时只能使用一个索引。如果您有单独的索引,它将选择其中一个,然后必须进行扫描以匹配另一列。如果您使用复合索引,它可以使用它同时匹配两列。
标签: mysql comparison