2012-09-05 74 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。 –

相關問題