【发布时间】:2012-11-15 16:15:00
【问题描述】:
假设我有这种查询
String sql = "SELECT s.team_id, s.team_name, s.gp, s.w, s.t, s.l, s.go, s.ga, s.score, s.p FROM "
+ "(SELECT team_id, team_name, SUM (gp) gp, SUM (w) w, SUM (t) t, SUM (l) l, SUM (GO) go, SUM (GA) ga, SUM (GO)- SUM (GA) score, SUM (2*w+t) p FROM "
+ "(SELECT t._id team_id, t.name team_name, COUNT(CASE WHEN score_home IS NOT NULL THEN 1 END) gp, COUNT (CASE WHEN score_home > score_away THEN 1 END) w,"
+ " COUNT (CASE WHEN score_home = score_away THEN 1 END) t, COUNT (CASE WHEN score_home < score_away THEN 1 END) l,"
+ " SUM (score_home) go, SUM (score_away) ga"
+ " FROM team_table t LEFT OUTER JOIN match_table m ON m.team_home = t._id"
+ " WHERE t.tournament_id = ? GROUP BY t._id, t.name"
+ " UNION ALL"
+ " SELECT t._id team_id, t.name team_name, COUNT(CASE WHEN score_away IS NOT NULL THEN 1 END) gp, COUNT (CASE WHEN score_home < score_away THEN 1 END) w,"
+ " COUNT (CASE WHEN score_home = score_away THEN 1 END) t, COUNT (CASE WHEN score_home > score_away THEN 1 END) l,"
+ " SUM (score_away) go, SUM (score_home) ga"
+ " FROM team_table t LEFT OUTER JOIN match_table m ON m.team_away = t._id"
+ " WHERE t.tournament_id = ? GROUP BY t._id, t.name)"
+ " GROUP BY team_id, team_name) s"
+ " ORDER BY s.p DESC, s.score DESC, s.go ASC";
然后像这样使用
Cursor cursor = database.rawQuery(sql, args);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
TeamStats stat = new TeamStats();
stat.setTeamId(cursor.getLong(0));
stat.setTeamName(cursor.getString(1));
stat.setGamesPlayed(cursor.getInt(2));
stat.setWins(cursor.getInt(3));
stat.setTies(cursor.getInt(4));
stat.setLoses(cursor.getInt(5));
stat.setGoalsOwn(cursor.getInt(6));
stat.setGoalsAgaist(cursor.getInt(7));
stat.setScore(cursor.getInt(8));
stat.setPoints(cursor.getInt(9));
stats.add(stat);
cursor.moveToNext();
}
cursor.close();
所以它从许多表中选择值,执行一些操作等。正如您所见,查询非常复杂(非常难以调试)并且性能似乎没有我预期的那么好。我的问题是:
- 我可以使用某种准备好的语句来提高性能吗?
- 执行更简单的查询并使用一些自定义代码手动处理它们会更快吗?
【问题讨论】:
-
改进您的数据库架构,对其进行反规范化,添加索引和类似的东西,以便您的查询变得更简单和更快。
EXPLAIN QUERY PLAN是查看 sqlite 对查询的作用的好方法 -
首先您应该考虑以某种可读的方式格式化查询。 stackoverflow 不应该是展示您可以创建混淆 sql 语句的地方。
-
@tkr 好吧...首先,拒绝您的更改是蹩脚的。其次,
String sql部分是必不可少的,因为下面的代码使用了它。这是我拒绝您的更改的主要原因。您不能只是删除所有周围的代码并期望我接受它。下一次,想想你的行为并表现自己...... -
String sql 对于这个问题不是必不可少的,“ + \n ”也不是。理解查询并以有意义的方式对其进行结构化应该是优化的第一步。您真的对答案感兴趣还是这只是暗示性的?
-
@tkr 我想我可以更好地决定问题中的重要内容。 SQL 查询本身并不那么重要,它只是可能的复杂性的一个示例。