优化循环选择语句

时间:2014-05-26 20:06:40

标签: php mysql query-optimization

所以我现在有一个数据库来保存调查问题,现在我想显示结果。 需要注意的事项:根据问题,每个问题可以有2-6个答案。

这些是我使用的表格以及一些示例数据:

 Table: answers_only         Table: questions_only
╔════════════════╦════════╗ ╔═════════════════╦═══════════════════╗
║ answer_ID (PK) ║ answer ║ ║question_ID (PK) ║ question          ║
╠════════════════╬════════╣ ╠═════════════════╬═══════════════════╣
║    65114       ║ yes    ║ ║       123       ║ Are you happy?    ║
╚════════════════╩════════╝ ╚═════════════════╩═══════════════════╝

                    Table: questions
╔════════════════╦══════════════════╦════════════════╦════════════════╗
║ unique_ID (PK) ║ question_ID (FK) ║ answer_ID (FK) ║ person_ID (FK) ║
╠════════════════╬══════════════════╬════════════════╬════════════════╣
║              1 ║              123 ║          65114 ║           5521 ║
╚════════════════╩══════════════════╩════════════════╩════════════════╝

所以我有一个表格问题,其中包含 questions_only 的ID(FK),其中包含实际问题。在这里,我抓住了回答的前100个问题:

$result = mysqli_query($con,"SELECT question, questions.question_ID AS question_ID 
FROM questions 
INNER JOIN questions_only ON questions_only.question_ID=questions.question_ID 
GROUP BY questions.question_ID 
ORDER BY COUNT(*) DESC limit 100");

接下来,我会回答每个问题并收集每个答案的数量:

while($row = mysqli_fetch_array($result)) {

    $question_ID = $row['question_ID'];

    $result2 = mysqli_query($con,"SELECT answer, COUNT(*) AS 'count' 
    FROM questions 
    INNER JOIN answers_only ON answers_only.answer_ID=questions.answer_ID 
    WHERE questions.question_ID= '" . $question_ID . "' 
    GROUP BY answer ORDER BY COUNT(*) DESC"); 
}

目前第一行代码大约需要8秒才能执行。第二部分(循环100个选择语句)正在耗费大约350秒。因此,我正在寻找更好的方法,因为目前在这种情况下它无法使用。目前,此代码在文档的head标签中运行。

1 个答案:

答案 0 :(得分:0)

当这样的事情花费很多时间时,也许你的服务器会超时。在这些情况下,解决问题的一种方法是为数据库提供每行输出的调用。也就是说,改变将数据分成几部分的策略,使连接保持活动状态,并为用户提供他们等待的每一秒的反馈。

可能会出现这样的程序:

// get all of the question ids that matter.
$result = mysqli_query($con,"SELECT questions.question_ID AS question_ID 
FROM questions DESC limit 100");  // or similar
// pack all of those into an array
$answerHolder = array();
while($row = mysqli_fetch_array($result)) {

    $question_ID = $row['question_ID'];
    $answerHolder[] = $questionID;
}
// iterate through that array to get the questions that match each id

foreach ($answerHolder as $item){
// use $item in a SQL call to get the question
// as each question is obtained, print it out to display or store it for later use
}

与此类似的程序模式的更改将有助于保持数据库连接的活跃性,并可能提供足够的及时反馈以保持用户的兴趣。只要他们等待超过10秒,您可能会考虑向他们提供某种进度声明,让他们知道程序正在运行。

这种方法不会快得多,但它可能会让用户和系统参与解决手头的问题。