php - 优化循环 select 语句

标签 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,其中包含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 个 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 秒时,您可能需要考虑向他们提供某种进度声明,让他们知道程序正在运行。

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

关于php - 优化循环 select 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23877037/

相关文章:

php - 使用 PHP 和 MySQL 从多个表的多列中选择 DISTINCT

mysql - Yii2 使用子查询而不是带有 id 的数组进行急切加载

mysql - 有没有办法改变我的sql中的用户主机

php - MySQL 更新查询速度慢

php - 带有 API 平台包的自定义 Symfony Action

php - 按键自动完成对 300 万行表的查询

php - 获取最近使用 PHP 时间最长的位置?

MySQL - 慢多子查询和 GROUP BY

mysql - 对具有 3 亿行和每秒 50-100 个查询的 MySQL innoDB 表的查询随机减慢

mysql - 在具有外部 .TXT 文件的 MySQL 表中存储 1000 多个(30-50 KB)文本的最佳方法?