2012-01-10 81 views
2

我有我的PHP應用程序(使用codeigniter)的用戶列表。每個用戶可能已經完成了總計約1000個字段的表格。其結構類似於此:高級MySQL加入。加快查詢

用戶

id|username|... 

completed_form_fields

id|formid|userid|fieldkey|data 

其中場關鍵的是隻對特定的表單域的唯一密鑰,即: 「FIRST_NAME」

我有一個用戶搜索頁面,人們可以過濾o UT特定的用戶通過他們選擇的字段(眼睛的顏色,種族,性別......)然後我需要顯示這些領域,所以我很願意(和目前有)像這樣的輸出:

$filteredmembers = array(
[0] = Object(
    [id] => 1 
    [username] => kilrizzy 
... 
    [fields] => Array(
     [fname] => Jeff 
     [gender] => Male 
     ... 

目前我的腳本顯然是永久性的,因爲我查詢了填寫此表單的所有成員,然後遍歷每個成員以查詢其所有字段。那麼根據標準+頁面/偏移量將其過濾掉。

我知道需要有一種方法來在一個查詢中一起加入這些我不熟悉

簡化我非常緩慢的代碼版本:

function get_members(){ 
    $this->db->select('u.*'); 
    $this->db->from('users AS u'); 
    $query = $this->db->get(); 
    if ($query->num_rows() > 0){ 
     $members = $query->result(); 
     //Get fields from each user 
     foreach($members as $mk => $mv){ 
      $fields = $this->get_form_fields($mv->id,1,true); 
      $members[$mk]->fields = $fields; 
     } 
     return $members; 
    }else{ 
     return false; 
    } 
} 
function get_form_fields($uid,$form,$values=false){ 
    $this->db->where('user', $uid); 
    $this->db->where('form', $form); 
    $query = $this->db->get('form_fields'); 
    if ($query->num_rows() > 0){ 
     $result = $query->result(); 
     return $result; 
    }else{ 
     return false; 
    } 
} 
+1

你能發佈你的代碼嗎? – bfavaretto 2012-01-10 20:20:03

+0

您的篩選條件應該是從completed_form_fields表中的信息動態構建的WHERE子句的一部分。我無法想象你正在嘗試什麼,但你可能還需要在用戶和completed_form_fields表之間進行INNER JOIN。 – 2012-01-10 20:21:32

+0

@bfavaretto - 添加了我的查詢樣本 – kilrizzy 2012-01-10 20:27:45

回答

1

有一個辦法,但它得到過於昂貴,你添加的領域越多。許多選擇以該形式存儲額外用戶數據的CMS也會發生同樣的情況。

你可以使用這個工作搜索SQL:

SELECT 
    users.*, 
    firstname.data AS firstname, 
    lastname.data AS lastname, 
    eyecolor.data AS eyecolor, 

FROM 
    users 
    LEFT JOIN completed_form_fields AS firstname ON firstname.userid = users.id AND firstname.fieldkey = "firstname" 
    LEFT JOIN completed_form_fields AS lastname ON lastname.userid = users.id AND lastname.fieldkey = "lastname" 
    LEFT JOIN completed_form_fields AS eyecolor ON eyecolor.userid = users.id AND eyecolor.fieldkey = "eyecolor" 

WHERE 
    firstname.data LIKE '%searchdata%' 
    OR lastname.data LIKE '%searchdata%' 
    OR eyecolor.data LIKE '%searchdata%' 

這種方法變得非常大,貴爲MySQL服務器添加表的更多。因此,我建議不要超過10-15個這樣的連接,然後再次,我會描述它以確保。

+0

這看起來像我需要這樣做。我希望有一個我不知道的魔法解決方案。謝謝! – kilrizzy 2012-01-10 21:13:14

0
SELECT u.username, f.formid, f.userid, f.fieldkey, f.data FROM user AS u 
LEFT JOIN completed_form_fields AS f 
ON f.userid = u.id 


you should look at indexing your userid, index(userid), via phpmyadmin or sql file 

mysql-indexes

0

我不知道我完全理解這個問題。您可以使用單個查詢來獲取所有用戶,所有的字段(基本上,這是菲利普建議):

SELECT u.username, f.* 
FROM user AS u 
    INNER JOIN completed_form_fields AS f 
    ON f.userid = u.id 
ORDER BY u.id, f.fieldkey 

過濾結果,加入WHERE條款與條件。例如,只得到fieldkey S 'K1', 'K2' 和 'K3' 的數據:

SELECT u.username, f.* 
FROM user AS u 
    INNER JOIN completed_form_fields AS f 
    ON f.userid = u.id 
WHERE f.fieldkey IN ('k1', 'k2', 'k3') 
ORDER BY u.id, f.fieldkey 

這是你在找什麼?