MySql在更新和插入时挂起

时间:2014-10-29 19:30:59

标签: mysql

我有一个电子商务网站,有许多从未使用过的旧产品。

我编写了一个代码来查找这些产品并将它们移动到另一个表中。

代码查找应删除的产品,并使用列should_delete = 1;

标记它们

这是复制产品的代码(count =要删除的产品的数量):

    while ($count>0)
    {
        if ( $db->Execute("insert into delete_product select p.* product p where p.should_delete ='1'  limit 500" )){
            $db->Execute("update product p set p.should_delete='2' where p.id_product in (SELECT `id_product` FROM deleted_products)");

        }

        $count-= 500;
        sleep(1);
    }

首先它运行得非常快,当我'显示进程列表'时,我发现查询需要1秒。

但后来变得很慢,查询需要1个小时。

我正在使用未被其他人使用的QA srv。

我有很多可用磁盘空间(3.5G)

数据库中有80308个产品。

和29511,标记为删除。

innodb中的数据库

现在已经运行了几个小时,但只复制了6500个。

'show processlist'显示'发送数据'状态

我错过了什么?为什么这些简单的查询太慢了?

我能够改进第二个查询 -

update product p
join deleted_products dp on p.id_product = dp.id_product
  set p.should_delete='2'
where p.should_delete='1'

但是插页仍然挂起。


这是同一代码的另一个版本,也挂起 -

    while ($count>0)
    {
        $fname = microtime(true);
        $db->Execute("SELECT * FROM product p where p.should_delete='1' LIMIT 500 INTO OUTFILE '/tmp/".$fname.".txt'");
        if ( $db->Execute("LOAD DATA INFILE '/tmp/".$fname.".txt' INTO TABLE deleted_products"
            )){
            $db->Execute("update product p join deleted_products dp on p.id_product = dp.id_product   set p.should_delete='2' where p.$should_delete='1'");
        }

        $count-= 500;
        sleep(1);
    }

这个版本挂起 -

 58 | root | localhost | prestashop2 | Query   | 29192 | NULL   | LOAD DATA INFILE '/tmp/1414615714.6019.txt' INTO TABLE deleted_products

看起来像deleted_products以某种方式锁定了,但这是我创建的新表,并且在其引用的代码中没有其他地方,并且没有其他人使用此srv。

2 个答案:

答案 0 :(得分:1)

每次循环播放时,deleted_products表都会增加。因此,当时间继续时,这部分查询正在增加:

 where p.id_product in (SELECT `id_product` FROM deleted_products)"

所以想象一下从500开始然后它到达1000,1500,......直到它非常慢。因此我的建议是在其中添加where条件。

&AnAwesomeNewVariable=501;
while ($count>0)
{
    if ( $db->Execute("insert into delete_product select p.*
         product p where p.should_delete . ='1'  limit 500" ))
{
 $db->Execute("update product p set 
 p.should_delete='2' where p.id_product in
 (SELECT `id_product` FROM deleted_products where
 id_product<&AnAwesomeNewVariable AND id_product >&AnAwesomeNewVariable-500)");

        }

    $count-= 500;
    &AnAwesomeNewVariable+=500;
    sleep(1);
}

答案 1 :(得分:0)

这是磁盘空间问题。我正在查看df -h中的错误驱动器,我添加了更多空间并且它已经解决了。