2

我有一个名为 users 的表,其中大约有 250,000 条记录。我有另一个名为 staging 的表,其中包含大约 75,000 条记录。Staging 只有一列,msisdn。我想检查用户中不存在暂存的多少行。

我有以下查询,我已经在一个小数据子集上进行了测试,它似乎工作正常:

SELECT
    s.*
    FROM staging s
        LEFT OUTER JOIN users u ON u.msisdn=s.msisdn
        WHERE u.msisdn IS NULL

然而,问题是当我尝试在 250k 用户的完整列表上运行此查询时。在我停止之前它运行了一个小时。有什么办法可以优化这个查询吗?

我已经开始对暂存中的数据子集运行查询,但这是非常手动的:

SELECT
    s.*
    FROM staging s
        LEFT OUTER JOIN users u ON u.msisdn=s.msisdn
        WHERE u.msisdn IS NULL
    LIMIT 0,10000

msisdn 是 staging 表的主键,但它不是表 users 的主键。我不知道这是否重要。

4

4 回答 4

4

首先,您可以通过 EXPLAIN 命令查看 MySQL 使用的索引。只需写EXPLAIN在您的查询前面,结果将显示它正在使用的索引(如果有的话)。据推测,如果它在如此(相对)小的数据集(如 250,000 条记录)上如此缓慢,那么它并没有利用非常有效的索引,您将能够看到在哪里。

像这样重写查询也可能会有所帮助NOT EXISTS

SELECT s.* FROM staging s
WHERE NOT EXISTS (SELECT 1 FROM users WHERE users.misdn = s.misdn)
于 2009-08-12T12:58:57.037 回答
1

msisdn在每个表的列上放置索引。由于它不是 PK on users,因此您需要在其上放置一个非聚集索引。这应该会极大地加快您的查询速度。

于 2009-08-12T12:57:40.547 回答
1

你可以做些什么来加快这个查询:

  • 确保 msisdn 在两个表中都有索引
  • 优化您的表格
  • 将 * 替换为 msisdn
于 2009-08-12T13:05:04.577 回答
0

我不确定这会快多少,但是您可以尝试类似的方法。

select msisdn
from staging
where msisdn not in (select msisdn from users)

此外,请确保两个表中的 msisdn 列都存在索引。这应该会大大加快速度。

于 2009-08-12T12:58:15.973 回答