Use sql query to leverage sqlite speed

This commit is contained in:
Jan Zípek 2022-09-04 09:42:12 +02:00
parent 3f163309ad
commit 9d172a41b6
Signed by: kamen
GPG Key ID: A17882625B33AC31
1 changed files with 40 additions and 39 deletions

View File

@ -14,13 +14,6 @@ type sensorValue struct {
Value float64 `json:"value"` Value float64 `json:"value"`
} }
func min(a, b int64) int64 {
if a < b {
return a
}
return b
}
func (s *SensorValuesService) Push(sensorId int64, value float64) (int64, error) { func (s *SensorValuesService) Push(sensorId int64, value float64) (int64, error) {
res, err := s.ctx.DB.Exec("INSERT INTO sensor_values (timestamp, sensor_id, value) VALUES (?, ?, ?)", time.Now().Unix(), sensorId, value) res, err := s.ctx.DB.Exec("INSERT INTO sensor_values (timestamp, sensor_id, value) VALUES (?, ?, ?)", time.Now().Unix(), sensorId, value)
@ -32,36 +25,7 @@ func (s *SensorValuesService) Push(sensorId int64, value float64) (int64, error)
} }
func (s *SensorValuesService) GetList(sensorId int64, from int64, to int64) ([]sensorValue, error) { func (s *SensorValuesService) GetList(sensorId int64, from int64, to int64) ([]sensorValue, error) {
intervalSize := to - from return s.getValueItems(sensorId, from, to, getAutoSensorValuesInterval(from, to))
batchSize := intervalSize
if intervalSize > 100*24*60 {
batchSize = 24 * 60
}
values := make([]sensorValue, 0)
current := from
for current < to {
nextValue := min(to, current+batchSize)
batchValues, err := s.getValueItems(sensorId, current, nextValue)
if err != nil {
return nil, err
}
sum := 0.0
for _, item := range batchValues {
sum += item.Value
}
values = append(values, sensorValue{Timestamp: int64((nextValue + current) / 2.0), Value: sum / float64(len(batchValues))})
current += batchSize
}
return values, nil
} }
func (s *SensorValuesService) GetLatest(sensorId int64, to int64) (*sensorValue, error) { func (s *SensorValuesService) GetLatest(sensorId int64, to int64) (*sensorValue, error) {
@ -77,10 +41,47 @@ func (s *SensorValuesService) GetLatest(sensorId int64, to int64) (*sensorValue,
return &value, nil return &value, nil
} }
func (s *SensorValuesService) getValueItems(sensorId int64, from int64, to int64) ([]sensorValue, error) { func (s *SensorValuesService) getValueListQuery(sensorId int64, from int64, to int64, divide int64) (*sql.Rows, error) {
if divide == 1 {
return s.ctx.DB.Query("SELECT timestamp, value FROM sensor_values WHERE sensor_id = ? AND timestamp > ? AND timestamp < ? ORDER BY timestamp ASC", sensorId, from, to)
}
return s.ctx.DB.Query(
"SELECT (timestamp/?)*?, AVG(value) FROM sensor_values WHERE sensor_id = ? AND timestamp > ? AND timestamp < ? GROUP BY (timestamp/?) ORDER BY timestamp ASC",
divide,
divide,
sensorId,
from,
to,
divide,
)
}
func getAutoSensorValuesInterval(from int64, to int64) int64 {
diff := to - from
// 360 days -> 1 day interval
if diff > 360*24*60*60 {
return 24 * 60 * 60
}
// 160 days -> 1 hour interval
if diff > 160*24*60*60 {
return 60 * 60
}
// 80 days -> 10 minutes
if diff > 80*24*60*60 {
return 10 * 60
}
return 1
}
func (s *SensorValuesService) getValueItems(sensorId int64, from int64, to int64, divide int64) ([]sensorValue, error) {
values := make([]sensorValue, 0) values := make([]sensorValue, 0)
rows, err := s.ctx.DB.Query("SELECT timestamp, value FROM sensor_values WHERE sensor_id = ? AND timestamp > ? AND timestamp < ? ORDER BY timestamp ASC", sensorId, from, to) rows, err := s.getValueListQuery(sensorId, from, to, divide)
if err != nil { if err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {