多次从一个相当大的表中提取数据的速度很慢

时间:2013-11-18 21:47:24

标签: php mysql database foreach

我目前正在我的网站上提供免费测试功能,每个用户可以参加其中一项测试并查看他们的高分或其他任何内容。

我有一个经历了每个测试的foreach并检查每个学生获得的最高年级。持有已保存测试的表格正在推动15,000行数据。

这里大致是我所拥有的:

foreach(testList as $test){

   SELECT saved_grade FROM system_saved 
   WHERE account_id = {{account_id}}
   AND test_id = {{test_id}}
   Order By saved_grade DESC
   LIMIT 0, 1

}

它要求每个测试必须扫描整个表格,以便每次都找到最高等级。

  • 是否有更好的方法为用户提供最高等级?
  • 索引表会有帮助(我真的不明白这个+ 每天都有新数据,我不确定索引是否正常 相关)
  • 还有什么你能想到的可以帮助它更快地运行吗? (它 目前需要大约20秒才能加载)

4 个答案:

答案 0 :(得分:1)

您无需单独选择每项测试。假设对于每个进行测试的人来说,account_id都是唯一的,而且saved_grade不是一个字符串,你应该能够做到这一点

SELECT MAX(saved_grade) 
FROM system_saved 
WHERE account_id = {{account_id}}
AND test_id = {{test_id}}

答案 1 :(得分:1)

不要循环;使用一个查询。这将检索每个学生的最佳成绩,由学生订购,然后通过测试。

SELECT account_id, test_id, MAX(saved_grade) as `best_grade`
FROM system_saved
GROUP BY account_id DESC, test_id DESC

要获得该学生任何考试的最佳成绩,请改用:

SELECT account_id, MAX(saved_grade) as `best_grade`
FROM system_saved
GROUP BY account_id DESC

编辑:如果您想知道他们获得最高分的测试,您可以这样做:

SELECT account_id, test_id, saved_grade
FROM system_saved WHERE (account_id, saved_grade) IN (
    SELECT account_id, MAX(saved_grade) as `best_grade`
    FROM system_saved
    GROUP BY account_id DESC)

答案 2 :(得分:0)

你可能应该使用max():

foreach(testList as $test){

   SELECT max(saved_grade) FROM system_saved 
    WHERE account_id = {{account_id}}
      AND test_id = {{test_id}}
}

答案 3 :(得分:0)

您正在寻找的解决方案是GROUP BY和聚合功能:

SELECT account_id, test_id, max( saved_grade ) as highest_grade
FROM system_saved 
GROUP BY account_id, test_id

同时为(account_id, test_id, saved_grade)创建索引,以获得比未索引数据更好的性能。