Php 优化循环select语句

Php 优化循环select语句,php,mysql,query-optimization,Php,Mysql,Query Optimization,所以我现在有一个数据库,保存调查问题,现在我想显示结果注意事项:根据问题的不同,每个问题可以有2-6个答案 以下是我正在使用的表格和一些示例数据: Table: answers_only Table: questions_only ╔════════════════╦════════╗ ╔═════════════════╦═══════════════════╗ ║ answer_ID (PK) ║ answer ║ ║question_ID (PK) ║ question

所以我现在有一个数据库,保存调查问题,现在我想显示结果注意事项:根据问题的不同,每个问题可以有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,其中只包含id(FK)到questions\u,其中包含实际的问题。在这里,我抓住了被回答的前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条select语句)消耗了大约350秒。因此,我正在寻找更好的方法来实现这一点,因为目前它在这种时候是不可用的。当前,此代码在文档的head标记中运行。

当类似的事情占用大量时间时,您的服务器可能会超时。在这些情况下,解决问题的一种方法是为数据库调用每一行输出。也就是说,改变将数据分成几个部分的策略,这些部分将保持连接的活力,并为用户等待的每一秒提供一些反馈

一个看起来像这样的过程可能会发生:

// 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秒,你可能会考虑为他们提供某种进度声明,让他们知道程序正在工作。
这种方法不会更快,但它可能会让用户和系统参与解决手头的问题。

1。您的索引是否设置在FK上?2.count(*)应该替换为count(fld)以提高性能。我刚刚检查了一下,有几列缺少了一些索引。实际上,这很有帮助,只需要25秒。关于count(),我实际上尝试了这两种方法,发现count()比使用列快一秒左右。如果删除order by子句,会得到什么计时?这里可能需要一个触发器+非规范化计数字段。目前,计时对于任何实际使用来说都是可怕的。很棒的建议。用户反馈绝对是关键。我同意你的看法。