简体   繁体   English

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

[英]Pulling data from a fairly large table multiple times is going slow

I currently am offering a free test taking feature on my site that each user may take one of the tests and see their high score or whatever. 我目前正在我的网站上提供一个免费的测试功能,每个用户可以参加其中一个测试,看看他们的高分或其他什么。

I have a foreach that goes through each test and checks to see what the highest grade is each student has gotten. 我有一个经历每个测试的foreach并检查每个学生获得的最高年级。 The table holding the saved tests is pushing towards 15,000 rows of data. 保存测试的表格正在推动15,000行数据。

here is roughly what I have: 这大致是我所拥有的:

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

}

Its requiring each test to have to scan the whole table to find the highest grade everytime. 它要求每个测试必须扫描整个表格,以便每次都找到最高等级。

  • Is there a better way of pulling the highest grade for a user? 是否有更好的方法为用户提供最高等级?
  • Would Indexing the table help this (I don't really understand this + new data is being put in everyday, I'm not sure if indexing is relevant) 索引表是否有助于此(我真的不明白这个+新数据每天都被放入,我不确定索引是否相关)
  • Is there anything else you can think of to help this run faster? 还有什么你能想到的来帮助它更快地运行吗? (It currently takes about 20 seconds to load) (目前需要大约20秒才能加载)

You dont need to select every test individually. 您不需要单独选择每个测试。 Assuming account_id is unique for every person doing the test, and that saved_grade is not a string you should be able to do this 假设对于每个进行测试的人来说,account_id是唯一的,并且saved_grade不是一个字符串,你应该能够做到这一点

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

Don't loop; 不要循环; use one query. 使用一个查询。 This will retrieve the best grade for each student, ordered by student, then by test. 这将检索每个学生的最佳成绩,由学生订购,然后通过测试。

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

To get the best grade on any test by that student, use this instead: 要在该学生的任何测试中获得最佳成绩,请使用以下内容:

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

EDIT: If you want to know the test on which they got the highest score, you can do this: 编辑:如果你想知道他们获得最高分的测试,你可以这样做:

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)

You maybe should use max() : 你可能应该使用max():

foreach(testList as $test){

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

The solution you are looking for is GROUP BY and agggregation function: 您正在寻找的解决方案是GROUP BY和agggregation函数:

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

Also create index for (account_id, test_id, saved_grade) to gain better performance than on unindexed data. 同时为(account_id, test_id, saved_grade)创建索引,以获得比未索引数据更好的性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM