2012-12-31 60 views
4

我在這裏有一個相當複雜的情況。我找不到一個更好的方法來解決這個問題,而不需要在進入該頁面時將SELECT查詢放入循環700多次的循環中(不用擔心,我使用array_chunk將數組拆分爲頁面)。我想這會是一個資源殺手,如果我在這裏使用查詢。正因爲如此,我在這裏問一個問題。在我的情況下避免循環內的查詢

我有這個大陣我需要循環上:

$images = scandir($imgit_root_path . '/' . IMAGES_PATH); 

$indexhtm = array_search('index.htm', $images); 
unset($images[0], $images[1], $images[$indexhtm]); 

現在,我有我的IMAGES_PATH與文件(影像)的所有文件名的數組。現在問題來了:

其中一些圖像在數據庫中註冊,因爲註冊用戶的圖像列在我的數據庫中。現在我需要根據上面的數組名稱檢索user_id

在循環中我只是這樣做:

foreach ($images as $image_name) 
{ 
    $query = $db->prepare('SELECT user_id FROM imgit_images WHERE image_name = :name'); 
    $query->bindValue(':name', $image_name, PDO::PARAM_STR); 
    $query->execute(); 
    $row = $query->fetch(PDO::FETCH_ASSOC); 
    $user_id = $row['user_id']; 

    echo $user_id; 
} 

這只是正常,但效率等於0。使用​​user_id我打算從imgit_users表中獲取其他的東西,如username,這將需要該循環內的另一個查詢。

這是太多了,我需要一個更簡單的方法來處理這個問題。

有沒有辦法在進入循環之前獲取那些user_id s並在循環中使用它們?

這是imgit_images表結構: imgit_images table schema

雖然這是imgit_users模式: imgit_users table schema

+2

您應該檢查',其中X IN(...)' http://stackoverflow.com/questions/9736284/mysql-where-in – mbinette

+0

說實話,我想過,但然後我再也不知道如何在循環中使用帶有user_ids的數組,然後獲取用戶名。我怎麼知道哪個'image_name'適合'user_id'和兩個不同的數組? – Aborted

+1

您可以在循環中選擇'user_id'和'image_name',這樣就可以獲得兩者之間的關聯。 – mbinette

回答

3

像這樣的工作(我不知道是否有可能準備WHERE IN查詢,因爲值#不明......否則,確保您sanatize $images):

$image_names = "'".implode("', '", $images)."'"; 
$query = $db->prepare("SELECT img.user_id, image_name, username 
         FROM imgit_images img 
         INNER JOIN imgit_users u ON u.user_id = img.user_id 
         WHERE image_name IN(".$image_names.")"); 
$query->execute(); 
while($row = $query->fetch(PDO::FETCH_ASSOC)) 
{ 
    echo $row['user_id']."'s image is ".$row['image_name']; 
} 

你可能需要稍微調整一下(還沒有測試過),但你似乎能夠做到,所以我並不擔心!

+0

嘿。它有點作用,但我的邏輯仍然被阻止,我無法弄清楚如果循環中的image_name等於我們從查詢中獲得的image_name,那麼如何檢查主循環(我循環'scandir()')的內部,所以我們可以將用戶名添加到該圖像。這是一個例子,我創建的方法(基於你的查詢)返回一個數組:'Array([user_id] => 4 [image_name] => 7E4c1i2.jpg [username] => DEATHMETALGORE)' – Aborted

+0

你是什麼意思?如果'image_names'不等於,它不會在查詢結果中結束!或者你的意思是說你想確保查詢結果中的順序與'$ images'中的順序相同? – mbinette

+0

我得到它的工作。我將添加一個pastebin.com鏈接,以顯示我是如何在第二秒完成的。非常感謝* mbinette *! – Aborted

1

你能不能只用在查詢的INNER JOIN,這樣循環的每個迭代將返回相應用戶的詳細信息。您的查詢更改爲類似(我正在做假設,你的表的結構在這裏):

SELECT imgit_users.user_id 
,imgit_users.username 
,imgit_users.other_column_and_so_on 
FROM imgit_images 
INNER JOIN imgit_users ON imgit_users.user_id = imgit_images.user_id 
WHERE imgit_images.image_name = :name 

這顯然不避爲一個循環的需要(你很可能使用字符串連接建立你的where子句中的IN部分,但你可能會在這裏使用連接),但它會在每次迭代時返回用戶的信息,並且不需要進一步的迭代來獲取用戶的信息。

1

不知道這是否會幫助,但我看到一對夫婦的優化,有可能的:

  1. 準備外循環查詢,反彈/執行/獲取循環中產生。如果查詢準備昂貴,則可能會節省相當多的時間。

  2. 您可以像Passing an array to a query using a WHERE clause那樣傳遞數組並獲取圖像和用戶標識,這樣您可以將查詢分割爲更少數量的查詢。