【发布时间】:2015-07-20 05:19:14
【问题描述】:
我正在循环 40 个关联数组:
array(
'key0' => value,
'url0' => value,
'tit0' => value,
'cdn0' => value,
'cdn1' => value,
'cdn2' => value,
)
我正在执行多个select 和一个可能 insert 查询。我尝试通过减少查询量来优化性能。
foreach($buf){
$sth1->execute();//SELECT * FROM metadata WHERE url = '{$buf['url0']}'
$sth2->execute();//SELECT * FROM metadata WHERE key = '{$buf['key0']}'
if(!$ret=$sth1->fetch(PDO::FETCH_ASSOC)){
if($sth2->fetch(PDO::FETCH_ASSOC)){
die( 'key duplicate - error' );
}
$data[ ] = $buf;
$sth3->execute();//INSERT INTO metadata ...
} else {
$data[ ] = $ret;
}
但这很慢(循环大约需要 4.2 秒)。我尝试通过删除查询使其更快。
foreach($buf){
$sth1->execute();//SELECT * FROM metadata WHERE url = '{$buf['url0']}' OR key = '{$buf['key0']}'
if(!$ret=$sth1->fetch(PDO::FETCH_ASSOC)){
$sth3->execute();//INSERT INTO metadata ...
$data[ ] = $buf;
} else {
if($ret['key']==$generated_key){die('key duplicate - error');}
$data[ ] = $ret;
}
由于某种原因,这使它变得更慢(5-6s)。因此,我一无所知。我怎样才能使它有一个合理的加载时间?我尝试将$sth2->execute 放在if(!$ret...) 语句中,但这也没有给我任何速度提升。
问题似乎不是INSERT,因为大部分array 数据已经是IN 数据库。每当我在 phpmyAdmin 中运行查询时,它会在 0.0000000003 秒内完成,因此它必须与循环有关。
【问题讨论】:
-
我会尝试对所有插入使用一个事务。它改变了数据库必须做的工作量以及何时做。在您的
foreach loop之前启动“事务”并在之后关闭它。意识到。任何错误,那么所有 40 次插入都需要再次完成。 -
完成。速度略有增加。 (0.2 秒)。谢谢。
-
嗯...这令人失望。我会建议“解释计划”并安排查询时间以查看它在哪里花费时间。我还会考虑在“foreach”循环之前“准备”查询。
-
@RyanVincent 有些查询只需要做两次插入,所以问题不在于那里。准备它们已经在 foreach 循环之前完成
-
在循环内执行查询会大大降低您网站的性能。如果您需要获取数百行,那么您的循环将进行数百次查询。避免这种情况的一种方法是映射您的
where凭据数组并在循环外使用WHERE IN执行单个查询。
标签: php mysql performance pdo mariadb