php - 高级 MySQL 连接。加速查询

标签 php mysql codeigniter join

我的 php 应用程序中有一个用户列表(使用 codeigniter)。每个用户可能已经完成了一个大约有 1000 个左右字段的表单。结构看起来类似于:

用户

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
        ...

目前,我的脚本显然耗时很长,因为我查询了所有填写此表单的成员,然后遍历每个成员以查询他们的所有字段。然后根据标准+页面/偏移量过滤掉那些。

我知道需要有一种方法将它们连接到一个我不熟悉的查询中

我的非常慢的代码的简化版本:

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;   
    }
}

最佳答案

有一种方法,但它会随着您添加的字段越多而变得越昂贵。许多选择以该形式存储额外用户数据的 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 次这样的连接,然后再一次,我会分析它以确保。

关于php - 高级 MySQL 连接。加速查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8809902/

相关文章:

php - 如何在单个页面中使用两个自动建议(ajax、PHP、Mysql)

mysql - 左连接和条件 where 求和

codeigniter - 如何将 Amazon S3 上的图像 404 错误重定向到我自己的服务器

javascript - 将 HTML 数组值存储到 javascript 数组中以通过 AJAX 发送

php - 为什么当我相继有两个 mysqli 查询时,我只能执行第一个查询?

Heroku 中的 PHP 错误日志

php - 从 View 中获取 "id"并传递到 CodeIgniter 中的另一个 View

php - 安全灵活的跨域 session

php - Nestable List 插件 PHP MYSQL L Json 树结构

php - 如何使用内部连接从 codeigniter 中的两个表中获取数据