我有一个电子商务网站,有许多从未使用过的旧产品。
我编写了一个代码来查找这些产品并将它们移动到另一个表中。
代码查找应删除的产品,并使用列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。
答案 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
中的错误驱动器,我添加了更多空间并且它已经解决了。