我在一个支持SQLite 3的小型Android应用上写作。 ATM我正在实现一些数据库功能,并问自己是否更好有一个大的连接查询,或者是否可以在App性能方面使用多个查询。
假设我有3个表“驱动程序”,“driven_runs”,“race_disciplines”。每个driven_run都有一个驱动程序和一个race_discipline。让我们假设我希望某个学科中的某个驾驶员获得所有种族纪律。
解决方案1
我已经编写了一个带有Driver-Object的函数getDriver(driverID)和一个带有Race Discipline的函数getRaceDiscipline(disciplineID)作为回报。所以我只想创建一个函数
public ArrayList<DrivenRun> getDrivenRunsOnDiscipline(short driverID, short disciplineID) {
ArrayList<DrivenRun> drivenRuns = new ArrayList<DrivenRun>();
String sql = "SELECT * FROM " + DBHelper.TABLE_DRIVEN_RUNS + " WHERE "
+ DBHelper.DRIVEN_RUNS_COLUMN_DRIVER_ID + "=" + driverID + " AND "
+ DBHelper.DRIVEN_RUNS_COLUMN_RACE_DISCIPLINE_ID + "=" + disciplineID + ";";
Cursor result = rawQuery(sql);
if (result.moveToFirst()) {
do {
Driver driver = getDriver(driverID);
RaceDiscipline discipline = getRaceDiscipline(disciplineID);
DrivenRun run = new DrivenRun();
run.setDriver(driver);
run.setDiscipline(discipline);
run.setResult("WHATEVER");
drivenRuns.add(run);
} while(result.moveToNext());
}
return drivenRuns;
}
在这种情况下,将会有3个查询一个接一个地执行,但编码要简单得多。
解决方案2
我会创建一个大的连接查询,如
String sql = "SELECT * FROM driven_runs CROSS JOIN drivers CROSS_JOIN race_disciplines WHERE driven_runs.driver_id=drivers.id AND driven_runs.race_discipline_id=race_disciplines.id"
Cursor result = rawQuery(sql);
并手动创建Driver和DrivenRun对象。
此解决方案需要更多写入,但只执行一个查询(或者,当连接3个表时,数据库是否也会执行3个查询?)
长话短说,是否可以使用解决方案1,因为在性能方面没有太大区别?
答案 0 :(得分:2)
一般情况下,请选择更简单的代码,直到有良好的性能原因为止。鉴于这是SQLite,我认为可能没有太大的性能差异,因为查询的开销非常低。
过早优化是万恶之源。
答案 1 :(得分:2)
你应该使用正确的连接语法,那么你的查询看起来不会那么麻烦:
SELECT THECOLUMNSYOUREALLYNEED
FROM driven_runs JOIN
drivers
on driven_runs.driver_id=drivers.id join
race_disciplines
on driven_runs.race_discipline_id=race_disciplines.id
where driver.id = YOURDRIVEIDHERE and race_discipline = YOURDISCIPLINEIDHERE
此外,只返回您需要的列。其次,在where
子句中插入适当的id。你的版本正在返回所有内容,这是完全没必要的。
这是一个非常简单的查询,它可以完成SQL数据库的最佳操作 - 将大型表连接在一起。即使使用SQLite,您最好还是让数据库完成工作。它至少会将一些往返通信从数据库层保存回应用层。
在更复杂的环境中,数据库将利用多个处理器,多个磁盘,并智能地缓存结果,以进一步优化查询响应。