avoid a SQLite3 sort in list_recordings_by_time

This fixes a minor performance regression for recording lists introduced in
eee887b by ordering by the start_time_90k (the natural order of the
recording_cover index) rather than the composite_id (which requires a sort
pass).

"explain query plan" before:
0|0|0|SEARCH TABLE recording USING INDEX recording_cover (start_time_90k>? AND start_time_90k<?)
0|0|0|USE TEMP B-TREE FOR ORDER BY

after:
0|0|0|SEARCH TABLE recording USING INDEX recording_cover (start_time_90k>? AND start_time_90k<?)

The list_aggregated_recordings algorithm is already designed to work in this
case; see the comments there. I must have forgotten to switch the order by
clause since writing that algorithm.

There's still a sort post-aggregation but that's over less data.
This commit is contained in:
Scott Lamb 2017-01-07 00:16:34 -08:00
parent 6f2b66c406
commit 3e58230813

View File

@ -783,8 +783,8 @@ impl LockedDatabase {
}
}
/// Lists the specified recordings in ascending order, passing them to a supplied function.
/// Given that the function is called with the database lock held, it should be quick.
/// Lists the specified recordings in ascending order by start time, passing them to a supplied
/// function. Given that the function is called with the database lock held, it should be quick.
pub fn list_recordings_by_time<F>(&self, camera_id: i32, desired_time: Range<recording::Time>,
f: F) -> Result<(), Error>
where F: FnMut(ListRecordingsRow) -> Result<(), Error> {
@ -796,6 +796,7 @@ impl LockedDatabase {
self.list_recordings_inner(camera_id, rows, f)
}
/// Lists the specified recordigs in ascending order by id.
pub fn list_recordings_by_id<F>(&self, camera_id: i32, desired_ids: Range<i32>, f: F)
-> Result<(), Error>
where F: FnMut(ListRecordingsRow) -> Result<(), Error> {
@ -1132,7 +1133,7 @@ impl Database {
recording.start_time_90k < :end_time_90k and
recording.start_time_90k + recording.duration_90k > :start_time_90k
order by
recording.composite_id
recording.start_time_90k
"#, recording::MAX_RECORDING_DURATION);
{
use std::error::Error as E;