2012-01-10 23 views
2

私はphpアプリケーション上のユーザのリストを持っています(codeigniterを使用しています)。各ユーザは、約1000フィールドのフォームを完成させることができます。高度なMySQLの結合。クエリの高速化

ユーザー

id|username|... 

completed_form_fieldsフィールドキーは、その特定のフォームフィールドのためだけの一意のキー、すなわちある

id|formid|userid|fieldkey|data 

: "FIRST_NAME" 構造は、これに似ています

私は、ユーザーがフィルタリングできるユーザー検索ページを持っています

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

私のスクリプト:UT、彼らが選択したフィールドによって、特定のユーザー(目の色、人種、性別は...)それから私は、私は大好きです(現在は持って)しまうので、このような出力をこれらのフィールドを表示する必要があります私はこのフォームに記入したすべてのメンバーに照会してから、各フィールドをループしてすべてのフィールドを照会するので、明らかに永遠に取っています。それから、基準+ページ/オフセットに基づいてそれらをフィルタリングします。

私は、私は私の非常に遅いコードの

簡易版に慣れていない午前1つのクエリで一緒にこれらを結合する方法が必要知っている:そこの方法があるが、それを取得

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

+0

フィルタ条件は、completed_form_fieldsテーブルの情報から動的に作成されるWHERE句の一部である必要があります。私はあなたが試みていることを想像することはできませんが、ユーザーテーブルとcompleted_form_fieldsテーブルの間にINNER JOINが必要な場合もあります。 –

+0

@bfavaretto - 私のクエリのサンプルを追加しました – kilrizzy

答えて

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

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 

は、これはあなたが探しているものですか?

関連する問題