具有大量数据的多个联接的MySQL查询

时间:2019-06-10 09:06:07

标签: mysql join query-optimization inner-join

我在数据库中有三个表

表格反馈响应

    resp_id(Primary) | name | mobile | pnr | message | added_on

表格feedback_response_items

    feed_item_id | resp_id | qn_id | ans_id

表feedback_answers

    ans_id(Primary) | ans_desc | qn_id

我想要的是显示 feedback_responses表中的所有行,并且每一行包含 feedback_response_items 中的9个项目,这些表与表 feedback_responses 的主键匹配这是 resp_id

因此,我将从中获得所有问题的ans_id,并在表 feedback_answers

中获得响应的答案描述。

,查询为

$f=$db->Query("
        SELECT fr.resp_id, fr.name, fr.mobile, fr.pnr, fr.message,
        (SELECT ans_id FROM feedback_response_items fr1 WHERE fr.resp_id = fr1.resp_id  AND fr1.qn_id='1') AS qn1Ans,
        (SELECT ans_id FROM feedback_response_items fr2 WHERE fr.resp_id = fr2.resp_id  AND fr2.qn_id='2') AS qn2Ans,
        (SELECT ans_id FROM feedback_response_items fr3 WHERE fr.resp_id = fr3.resp_id  AND fr3.qn_id='3') AS qn3Ans,
        (SELECT ans_id FROM feedback_response_items fr4 WHERE fr.resp_id = fr4.resp_id  AND fr4.qn_id='4') AS qn4Ans,
        (SELECT ans_id FROM feedback_response_items fr5 WHERE fr.resp_id = fr5.resp_id  AND fr5.qn_id='5') AS qn5Ans,
        (SELECT ans_id FROM feedback_response_items fr6 WHERE fr.resp_id = fr6.resp_id  AND fr6.qn_id='6') AS qn6Ans,
        (SELECT ans_id FROM feedback_response_items fr7 WHERE fr.resp_id = fr7.resp_id  AND fr7.qn_id='7') AS qn7Ans,
        (SELECT ans_id FROM feedback_response_items fr8 WHERE fr.resp_id = fr8.resp_id  AND fr8.qn_id='8') AS qn8Ans,
        (SELECT ans_id FROM feedback_response_items fr10 WHERE fr.resp_id = fr10.resp_id  AND fr10.qn_id='10') AS qn10Ans
        FROM feedback_responses fr
        "); 

上面的查询需要花费很多时间(超过2分钟)来执行如何优化它,我对此感到震惊,任何反馈将不胜感激。

2 个答案:

答案 0 :(得分:1)

这可能无法完全满足您的答案,因为可能需要进行一些编程:

您忽略了为各种表指定的索引。对于表 feedback_response_items ,您应该至少在 resp_id 列上定义索引(而在 qn_id 上定义一个索引)。如果不是这样,请查看这样做如何减少执行时间。

如果您已经定义了索引,或者定义索引并没有显着改善执行时间,则需要进行一些编程。您的SQL应该是:

SELECT fr.resp_id, fr.name, fr.mobile, fr.pnr, fr.message, fri.ans_id /*, fa.ans_desc */
FROM feedback_responses fr
JOIN feedback_response_items fri ON fr.resp_id = fri.resp_id    
                                    AND fri.qn_id IN ('1','2','3','4','5','6','7','8','10')
/* JOIN feedback_answers fa on fri.ans_id = fa.ans_id */
ORDER BY fri.qn_id
;

删除上述SQL中的注释,也可以获取答案。现在,对于fr.resp_id的每个值,将返回9行。该SQL的意图是由计算机程序发出,该计算机程序将处理9行的组并根据需要显示结果。

答案 1 :(得分:1)

我认为,如果您在select语句中移动子查询,并加入项目表,则查询将非常快地运行! (似乎子查询针对每一行执行,因此需要时间)。这将起作用:

SELECT fr.resp_id, fr.name, fr.mobile, fr.pnr, fr.message,
MAX(IF(fri.qn_id='1',ans_id,0)) AS qn1Ans,
MAX(IF(fri.qn_id='2',ans_id,0)) AS qn2Ans,
MAX(IF(fri.qn_id='3',ans_id,0)) AS qn3Ans,
MAX(IF(fri.qn_id='4',ans_id,0)) AS qn4Ans,
MAX(IF(fri.qn_id='5',ans_id,0)) AS qn5Ans,
MAX(IF(fri.qn_id='6',ans_id,0)) AS qn6Ans,
MAX(IF(fri.qn_id='7',ans_id,0)) AS qn7Ans,
MAX(IF(fri.qn_id='8',ans_id,0)) AS qn8Ans,
MAX(IF(fri.qn_id='10',ans_id,0)) AS qn10Ans,
FROM feedback_responses fr
JOIN feedback_response_items fri ON fr.resp_id = fri.resp_id 
GROUP BY fr.resp_id, fr.name, fr.mobile, fr.pnr, fr.message

希望对您有帮助!