2012-09-05 60 views
1

我有一个时间相关的脚本,我正在使用microtime()来查找瓶颈。我确定时间增加是由于检查300多个值来查看它们是否存在于一个数据库中,每次查询时间为0.04秒。PDO检查数据库中是否存在300多个值的最佳方法

脚本的背景是它是一个缓存脚本。我需要看看它是否存在于数据库中,所以我需要一个true/false(由rowCount获得),但我也需要一种方法将false与值关联起来,以便我可以更新它。我知道使用WHERE标记IN(:ARRAY)会比单个调用更快,但我不能想到在此方法中将true/false关联应用于值的方法。

我当前的代码如下:

//loop through all our values! 
    //prepare out reusuable statement 
$stmt = $db->prepare("SELECT * from cache WHERE value=?"); 

foreach($values as $tempVal) 
{ 
    //find if its in the database 
    try 
    { 
     $stmt->execute(array($tempVal)); 
     $valCount = $stmt->rowCount(); 
    } catch(PDOException $ex) { 
     echo "PDO error send this to us: " . $ex->getMessage(); 
    } 

    //update flag 
    $addToUpdate = 1; 

    //if its in the database 
    if($valCount > 0) 
    { 
     //get the tag data 
     $valRes= $stmt->fetch(); 

     //check if cache expired 
        $addToUpdate = 0; 
    } 

    //add to update list 
    if($addToUpdate) 
    { 
        //needs updating 
     $updateList[] = $tempVal; 

     //add to not in DB list to minimize queries 
     if($tagTCount == 0) 
     { 
      $notInDB[$tempVal] = $tempVal; 
     } 
    } 

有什么建议?如果有什么不清楚的话,我可以解释更多。

谢谢 尼克

+3

您最好使用'value IN(?,?,?,?,?,?,...)'代替循环。使用一个PDO包装库,从你的数组/列表生成SQL查询。你确实从'SELECT *'获得了应该包含单个'value'值的关联。将返回的列表映射到您的PHP源数组。 – mario

+0

@mario所以你是说每个fetch()都会返回select或“null”,这取决于与存在的标记相关的标记(大概是为了将它放入IN数组中)? –

回答

2

这样你只要发出与一系列完整查询,使用IN (?,?,?,?,?...)列表:

// abstract, use a PDO wrapper of your choosing 
$query = db("SELECT * FROM cache WHERE value IN (??)", $values); 

然后在结果列表进行迭代。只有匹配的$值才会返回。于是从建立第一个列表:

foreach ($query as $row) { 
    $updateList[] = $row["value"]; 
} 

要获得缺席条目列表,只是diff,对原来的数组:

$notInDB = array_diff($values, $updateList); 

你当然可以使用第二NOT IN查询。但在PHP中做这种差异更简单。

+0

字面意思是从14秒减少到1.感谢您帮助我解决这个问题,我期待为未找到的值获得NULL。 –

相关问题