访问超过1000万行的MySQL表=错误:连接太多

时间:2011-03-13 15:08:35

标签: mysql mysql-management

如何优化访问两个表的MySQL查询,每个表的行数超过1000万?

以下查询的作用是,它从“用户”表中获取“来宾”表中不存在的所有ID。因此,这将返回数十万行,因此我们将其限制为每次运行至少获得5000个id。有没有更好的方法来运行它,以便我们可以在每次运行中完成更多工作。

    $before = date here before in time;
$now = date now;

$query="SELECT users.id 
    FROM users   
    LEFT JOIN guests ON guests.id = users.id    
    WHERE guests.id IS NULL AND (users.in >= '$before' AND users.in <= '$now')
    LIMIT 0,5000";

在我们知道guest虚拟机表中不存在哪些ID之后,我们必须删除users表中的那些行。所以这意味着它将运行另外5000个删除查询来删除所有这些ID。

如果我们使用包含超过1000万行数据的两个表运行此过程,我们的服务器将返回一个错误,即它有太多的连接,并且在重新启动之前无法再访问MySQL服务器。但是如果我们使用包含超过几千行的两个表运行相同的进程,它不会遇到这个问题,但它仍然需要一些时间。

为什么会发生这种情况,我们怎样才能避免这种情况同时优化这一过程。

2 个答案:

答案 0 :(得分:1)

2件事 - 检查您的软件如何处理MySQL连接。看起来它打开一个持久连接,然后不重用它,并且在每次查询之前都有一个新的连接。

其次 - 您可以修改查询以在一个语句中执行此操作,而不是对每个用户运行单独的查询。这样只需要一个连接,并且所有处理都将在MySQL端进行,这将能够进一步优化它。

编辑:您可以检查的另一件事是在查询上运行EXPLAIN以确保您已设置所有正确的索引(如果选择部件现在运行缓慢)。

答案 1 :(得分:0)

警告:在运行实时数据之前测试此查询。我不对任何丢失的数据负责

DELETE 
  u
FROM
  users AS u 
LEFT JOIN
  guests AS g 
ON g.id = u.id
WHERE 
  g.id IS NULL 
  AND (users.in >= '$before' AND users.in <= '$now')

关于你的问题的核心(连接太多),我怀疑你的PHP脚本是在循环中为要删除的ID启动新连接。