我在SQLITE中有一个高分表,它支持三个简单的操作:
public static String GetLocalMasterFileStream(String Operation) throws Exception {
String FullPath = "/sdcard/CM3/advices/advice_master.txt";
String line;
String return_value = "";
System.out.println("path is " + FullPath);
File file = new File(FullPath);
if (file.canRead() == true) {System.out.println("Determined that file is readable...");}
//Read text from file
StringBuilder text = new StringBuilder();
BufferedReader br = new BufferedReader(new FileReader(file));
if (Operation.equals("PreCheck")) {
line = br.readLine();
text.append(line.toString() + "\r\n");
return_value = String.valueOf(text);
} else {
//add some other stuff to do later here
}
br.close();
System.out.println("value being returned is> " + return_value);
return return_value;
}
一切正常,但我担心这会如何扩展:有10,000名用户排序高分需要~60ms这是可以的,但这次大致线性上升,这样如果我有100,000名用户请求高分会需要~600ms,这太慢了。
是否有一种智能的方式来插入新用户/更新他们的分数,以避免在我检索排行榜时必须进行完整的排序?例如。类似于C ++ priority_queue或python heapq。
我想我可以在每个插页上对整个数据库进行排序和替换(例如Sort an entire SQLite table),但这看起来有点过分。
答案 0 :(得分:4)
如果您担心order by
中select
的效果,请创建索引。对于简单的查询,例如:
select s.*
from scores s
order by s.high_score desc;
您需要scores(high_score)
上的索引:
create index idx_scores_highscore on scores(high_score desc);
答案 1 :(得分:1)
排序/排序是在SELECT
而非INSERT
上完成的。当查询没有明确定义时,关系数据库不保证排序顺序。
一般情况下,可能你会在查询任何给定的表时以相同的顺序获取记录,特别是如果主键是一个简单的自动递增数字,因为DB可能会使用PK作为排序(如果它是聚集索引)。但它不能保证。一旦你开始加入其他表,所有的赌注都会被取消,因为数据库有更多的逻辑来优化该查询。
基本上,如果您想按特定顺序取回记录,则必须在SELECT
中指定该订单。
如果性能有问题,请对查询进行概要分析并查找性能问题。排序列是否已编入索引?是否在某处执行全表扫描?还有别的什么问题?确定查询的执行计划并解决特定的瓶颈。
答案 2 :(得分:1)
正如其他人所说,需要在“选择”部分进行排序。
以下是一些性能提示:
仅查询您真正需要和关心的数据。如果您不需要,请不要选择所有列。如果您只对“前20名”感兴趣,请限制您的结果。
缓存输出。这意味着:存储“选择”的结果,并使对表的更改使缓存无效。您可以使用触发器自动实现此功能,但在处理数据时“手动”执行此操作也应该很容易。